JUnit testing with Acegi Security
Here's a tip if you are trying to do some unit testing with Acegi Security - particularly if you are doing role based authorization of method calls on your manager objects via interception.
Basically, a secure method interceptor will a) need an authentication token to play with, and b) a way to find out what authorities the user has. We need to cater for this when running the tests.
Acegi Security conveniently provides a TestingAuthenticationToken for unit testing purposes so we are Ok with the token part. You will now need to provide a suitable authentication provider. Somewhat unsurprisingly, there is a TestingAuthenticationProvider that you can add to your Spring config file to accommodate this.
But here is the problem: we already have this configured for production using a different provider (obviously), so we would have to resort to changing the config files depending on if you are running tests or not. This is too fragile for me, so here is the essence of the tip: leave the configuration file alone and dynamically changes the provider in the setup of the unit test.
Here is some code that I have in my JUnit setUp() method:
// Grant all roles to noddy.
TestingAuthenticationToken token = new TestingAuthenticationToken(
"noddy", "test", new GrantedAuthority[] {
new GrantedAuthorityImpl("User"),
new GrantedAuthorityImpl("Administrator") });
// Override the regular spring configuration
ProviderManager providerManager = (ProviderManager) ctx.getBean("authenticationManager");
List list = new ArrayList();
list.add(new TestingAuthenticationProvider());
providerManager.setProviders(list);
// Create and store the Acegi SecureContext into the ContextHolder.
SecureContextImpl secureContext = new SecureContextImpl();
secureContext.setAuthentication(token);
ContextHolder.setContext(secureContext);
So... it sets up an authentication token, then resets the authentication managers' provider list with one that contains the TestingAuthenticationProvider. It then creates the context for the method execution.
The problem with this is it does it for every single test method - that is how JUnit works for better or worse.
Hope it proves useful for you.
Update 2007-01-31: I've updated this to work with Acegi 1.0.3 and Spring 2.0.2.
Posted by: Brian Topping | 2006.07.31 at 06:40 PM
Posted by: Paul | 2006.12.13 at 01:07 PM
Posted by: Frode Reinertsen | 2007.01.16 at 10:28 AM
Posted by: Anna SkawiĆska | 2008.03.12 at 05:46 AM
Posted by: Phil Haigh | 2008.07.07 at 06:48 AM