Tag Archives: Spring MVC

Friday Fixes

It’s Friday, and time again for some Friday Fixes: selected problems I encountered during the week and their solutions.

This week’s challenges were all over the place, but I’ll focus in on just a couple of fixes in one popular category: Spring Security.

Filters : MVC :: Oil : Water

The web app I’m currently working on has some unique functions that occur at login.  Sure, it all starts with a login form, but it goes far beyond the simplified functions of standard Java EE form authentication.  Good news is, Spring MVC makes implementing these login functions nice, while Spring Security provides many of the protections we need. Bad news is, Spring Security and Spring MVC don’t play together at all.

A key reason is that Spring Security’s access control and authentication mechanisms are called upstream in the filter chain (before the controllers) and can’t access the controller’s state, session, and request.  With forms authentication (LoginUrlAuthenticationEntryPoint, UsernamePasswordAuthenticationFilter, and the like), you get one monitored post URL for authentication (by default,  j_spring_security_check) with no means for the controller to do sophisticated validation or page flow.

If I could lock myself into the strict confines of form authentication, then Spring Security’s implementation would be helpful: outside a bit of XML namespace configuration, all I’d need is a simple UserDetailsService DAO.  But I couldn’t, and trying to force it just convinced me that I really didn’t want Spring Security’s forms authentication after all.  What I really wanted was a Spring MVC login process which passed authentication details to Spring Security when done.

That part was very easy.  I just wrote a small utility class which, after it authenticated the user and retrieved his authorities, simply set them in Spring Security’s context.  Like so:

/**
 * Notify Spring Security that we've logged in and initialize
 * authorities for downstream filtering.
 */
public void login(MyUser myUser, HttpSession session) {
	List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();	
	for (String str : myUser.getAuthorities()) {
		authorities.add(new SimpleGrantedAuthority(str));
	}
	UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
				myUser.getUserId(), myUser.getPassword(), authorities);	   
	SecurityContext securityContext = SecurityContextHolder.getContext();
	securityContext.setAuthentication(auth);
	session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);		
}

To update Spring Security at logoff, I just did this:

SecurityContextHolder.getContext().setAuthentication(null);

This made Spring Security and me both happy, with no need to mix the oil of Spring MVC controller flow with the water of Spring Security authentication filters.

Casting Custom SPeLs

Among its many uses, the Spring Expression Language (SpEL) allows for flexible URL filter (intercept-url) expressions.  And custom expressions can be used to support unique access control requirements through simple configuration.

The T(my.package.Class).myMethod(whatever) syntax was one option, but that’s ugly, limited, and prone to error.  Further, by stepping through the code, I learned that the expression handlers called in Spring Security have access to all sorts of useful information to make authorization decisions.  So building my own custom expression evaluator was just the ticket.

But plugging in a custom expression handler took some maneuvering.  Turns out, you can’t just add a new SecurityExpressionRoot directly in the security configuration; you have to swap in a custom SecurityExpressionHandler and have it instantiate the evaluator, like so:

public class MySecurityExpressionHandler extends DefaultWebSecurityExpressionHandler {
	@Override
	protected SecurityExpressionRoot createSecurityExpressionRoot(
				Authentication authentication, FilterInvocation fi) {
		WebSecurityExpressionRoot root = 
				new MySecurityExpressionRoot(authentication, fi);
		root.setPermissionEvaluator(getPermissionEvaluator());
		return root;
	}
}

To round out the example, here’s a template for the custom evaluator and security context configuration.

public class MySecurityExpressionRoot extends WebSecurityExpressionRoot {
	public MySecurityExpressionRoot(Authentication a, FilterInvocation fi) {
		super(a, fi);
	}	
	public boolean canIDoThis() {
		// Your clever authentication here.
		// 'this' has access to the authentication token, request, and other goodies.
		// If conditions are satisfied, return true; otherwise...
		return false;
	}
}
<http use-expressions="true" ... >   	
	<intercept-url pattern="/public/stuff/**" access="permitAll"/>  
	<intercept-url pattern="/private/stuff/**" access="denyAll"/>  
	<intercept-url pattern="/members/only/stuff/**" access="isAuthenticated()"/>  
	<intercept-url pattern="/conditional/stuff/**" access="canIDoThis()"/>        
	<expression-handler ref="mySecurityExpressionHandler" />
 
	... other configuration ...
</http>	
<beans:bean id="mySecurityExpressionHandler"
         class="com.writestreams.security.MySecurityExpressionHandler"/>

Note that using expression-handler under http requires Spring Security 3.1 or higher, or at least an XSD patch.

Linkapalooza

Some useful / interesting links that came up this week:

Friday Fixes

Friday Fragments served a useful purpose, one of which was regularity: funny how Fridays kept coming around.  While I haven’t been in pedagogical fragment mode for awhile, I encounter real life puzzles every day.  Sharing these often helps others who encounter the same problems, or even myself when I need a quick reference down the road.  I just need a reminder and motivator to stop and record these.  I suppose Friday is as good as any.

So here goes the first installment of Friday Fixes: selected problems I encountered during the week and their solutions, along with other sundries.

Spring Loading

Like most form tags, binding a multi-select list in Spring MVC is easy: deceptively so.  All you need is this, right?

<form:select path="myFavorites" id="myFavorites" size="3" multiple="true" class="myList">
	<form:options items="${allChoices}" />
</form:select>

And, of course, the model attribute and/or bean methods to return the allChoices collection and get/set myFavorites.  Well, not so fast.  Turns out, multi-select lists in Spring MVC have always been a bit of a pain, particularly when it comes to making the initial selections (convincing Spring to add the selected attributes) on initial page load.  One pre-selection is fine, but with multiples, the comma-separated list pushed back into the model’s setter is a one-way trip.

Solving this in prior versions of Spring required using an InitBinder whether you otherwise needed one or not.  But for Spring MVC 3, the fix is to just map to collection getter/setters, even if your model wants to use the comma separated list.  For example, use the following getter and change the form:select path to use it: path=”myFavoritesList.

	public List getMyFavoritesList() {
		List list = new ArrayList();
		for (String fav : getMyFavorites().split(",")) {
			list.add(fav);
		}
		return list;
	}

Time(outs) May Change Me…

Between the deadlock event monitor, db2pd, and snapshots, DB2 has long provided good tools for tracking down deadlock culprits.  But for lock timeouts, not so much.  The DB2 folks have tried to improve things lately, but they’ve changed their minds a lot, often adding new tools and then quickly taking them away.

Now that lock timeout event monitors are finally here, many of the other new approaches like db2_capture_locktimeout and db2pdcfg -catch (with db2cos call-out scripts) have been deprecated.  A coworker was concerned about the passing of db2_capture_locktimeout, but it appears it’ll be around a little longer.  For example, the following still works in even the latest 9.7 fixpacks.

db2set db2_capture_locktimeout=on
db2stop & db2start
db2 get db cfg for sample show detail | find /i "timeout"
db2 update db cfg for sample using locktimeout 30
db2 connect to sample
db2 -c- update org set deptname=deptname

Repeat the last two commands in another DB2 Window and then wait for the timeout.  Look for the report under your DIAGPATH, SQLLIB, or Application Data folder; for example: dir db2locktimeout*.* /s.  Even with the latest 9.7 fixpacks, the timeout report can occasionally have some holes in it (like missing SQLs), but it’s still quite useful.

Flexigrid Incantation

Got a Flexigrid with a radio button?  Want to fetch the value of a column on the radio-selected row?  Well, when Flexigrid generates the tds and divs from your colModel, it provides abbr attributes, not ids.  So the usual jQuery shorthands to find by ID don’t apply, and you’re off chasing the more obscure abbr.  For example:

$('.mytable').find('tr').each(function (index, tr) {
	if($(tr).find('input#sequence').attr('checked')) {
		myvalue = $(tr).find('div#myname').val();          // Nope, doesn't work
		myvalue = $('td[abbr="myname"] >div', tr).html();  // Gotta use this
	}
});

New Toys

My own little Linkapalooza of online tools I found this week and actually used: