I'm trying to write a custom method security interceptor. However, it isn't using the authentication manager I added to the bean properties in my security context and returning null when I check to see if the authentication manager exists. Could anyone shed light on why the authentication manager bean property isn't being used? I'm using spring security 3.0.5 on WebSphere 7.0
Here's the bean containing the method interceptor
<beans:bean id="methodInterceptor"
class="bigbank.security.CustomMethodSecInterceptor">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="accessDecisionManager" ref="universalAccessDecisionManager" />
<beans:property name="securityMetadataSource" ref="tspmMethodSecurityMetaData" />
Here's my method security interceptor
public class CustomMethodSecInterceptor extends MethodSecurityInterceptor {
private static final Log logger = LogFactory
.getLog(WebSphere2SpringSecurityPropagationInterceptor.class);
private AuthenticationManager authenticationManager = null;
private AuthenticationDetailsSource authenticationDetailsSource = new WebSpherePreAuthenticatedAuthenticationDetailsSource();
private final WASUsernameAndGroupsExtractor wasHelper;
public CustomMethodSecInterceptor() {
wasHelper = new DefaultWASUsernameAndGroupsExtractor();
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
logger.debug("Performing Spring Security authentication with WebSphere credentials");
System.out.println("@@going through ss authentication");
authenticateSpringSecurityWithWASCredentials();
InterceptorStatusToken token = super.beforeInvocation(mi);
logger.debug("Proceeding with method invocation");
Object result = mi.proceed();
return super.afterInvocation(token, result);
} finally {
logger.debug("Clearing Spring Security security context");
SecurityContextHolder.clearContext();
}
}
private void authenticateSpringSecurityWithWASCredentials() {
Assert.notNull(authenticationManager); // This is where the error is coming up
Assert.notNull(authenticationDetailsSource);
String userName = wasHelper.getCurrentUserName();
if (logger.isDebugEnabled()) {
logger.debug("Creating authentication request for user " + userName);
}
PreAuthenticatedAuthenticationToken authRequest = new PreAuthenticatedAuthenticationToken(
userName, "N/A");
authRequest.setDetails(authenticationDetailsSource.buildDetails(null));
if (logger.isDebugEnabled()) {
logger.debug("Authentication request for user " + userName + ": "
+ authRequest);
}
Authentication authResponse = authenticationManager
.authenticate(authRequest);
if (logger.isDebugEnabled()) {
logger.debug("Authentication response for user " + userName + ": "
+ authResponse);
}
SecurityContextHolder.getContext().setAuthentication(authResponse);
}
public void setAuthenticationManager(
AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
}
Here's the error:
Caused by: java.lang.IllegalArgumentException: An AuthenticationManager is required
at org.springframework.util.Assert.notNull(Assert.java:112)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.afterPropertiesSet(AbstractSecurityInterceptor.java:118)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1469)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1409)
... 119 more
You have overridden the setAuthenticationManager
method, so when it is invoked by Spring to inject the AuthenticationManager
, it doesn't set the corresponding field in AbstractSecurityInterceptor
.
Since the base class contains a getter for this property, you would be best to remove the field and setter method, and just use the getter to access the authentication manager in your code.