I've overwritten the BasicAuthenticationFilter and replaced it with our a filter to fetch a custom Authentication object from db and set it via
SecurityContextHolder.getContext().setAuthentication(auth);
Here is the important fraction of the security config:
<http use-expressions="true" entry-point-ref="authEntryPoint">
<custom-filter position="BASIC_AUTH_FILTER" ref="basicProcessingFilter" />
<intercept-url pattern="/**" access="hasRole('user')"/>
</http>
<beans:bean id="authEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/login"/>
</beans:bean>
<global-method-security jsr250-annotations="enabled"/>
I also provide my own AuthenticationProvider which simply is a no-op because the authentication process is already done in the custom filter:
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
logger.info("user:" + authentication.getPrincipal() + " pw:" + authentication.getCredentials());
authentication.setAuthenticated(false);
return authentication;
}
@Override
public boolean supports(Class<? extends Object> authentication) {
return MyAuthentication.class.isAssignableFrom(authentication);
}
Now, Spring correctly prints the required role(s) for every method on start, so it detects the annotations correctly. E.g. the 'admin' role for a delete method:
2011-11-22 11:47:09,474 [main] DEBUG org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource - Adding security method [CacheKey[com.somecompany.SomeClass; public com.somecompany.ReturnType com.somecompany.SomeClass.delete()]] with attributes [admin]
But Spring does not check somehow if the user has this role. Instead it falls back to the global pattern defined in the http tag of the security context xml file. So, e.g. if I access this delete method with a user of roles:["user"] it will accept it because of the hasRole('user') in the http tag.
Probably it is something wrong when initializing the DefaultFilterInvocationSecurityMetadataSource object because it won't be filled with a specific rule for the delete method!? Only the http-tag defined rules are added via the addSecureUrl method.
What could be wrong?