BlazeDS, Spring, and Acegi Security - Part 2
In an earlier post I talked about BlazeDS and Spring Security and gave a high level overview of how to get a BlazeDS destination to be secured with Acegi security instead of BlazeDS’ security. However, I overlooked a simple thing that would make the whole system play nicer with Flex. That is, I didn’t translate the authentication exception into a flex.messaging.SecurityException and did not set its code to Client.Authentication. It’s not really necessary to do so as you will get an error message anyway because BlazeDS catches Acegi’s exception and wraps it in a MessageException, but it’s nicer if it’s wrapped in a semantically appropriate exception.
I first thought I’d add an exceptionTranslationFilter to my filterChainProxy but this doesn’t work because BlazeDS wraps the exception after the proxied bean invocation and doesn’t let it percolate to the container filter. Duh! That took me about an hour to figure out.
The next step would have been to pass an afterInvocationManager to the method SecurityInterceptor but this guy never gets called when an exception occurs.
So, the next step, which I think is kinda hacky, is to extend the MethodSecurityInvocation class and override invoke. Catch any AuthenticationExceptions and translate them into SecurityExceptions so that BlazeDS can transfer that exception to Flex as appropriate. Here’s the code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <pre lang="Java" line="1">
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return super.invoke(mi);
} catch (AuthenticationException ae) {
SecurityException se = new SecurityException();
se.setMessage(ae.getLocalizedMessage());
se.setRootCause(ae);
se.setDetails(ae.getLocalizedMessage());
// This is an authorization error instead of an auth error
if (ae instanceof InsufficientAuthenticationException) {
se.setCode(SecurityException.CLIENT_AUTHORIZATION_CODE);
}
else {
se.setCode(SecurityException.CLIENT_AUTHENTICATION_CODE);
}
throw se;
}
} |
My next step is to bypass BlazeDS’s authentication mechanism and just do it through Acegi. I’ll keep you posted.