I have custom authentication filter which creates PreAuthenticatedAuthenticationToken and stores it in security context. The filter works fine, it creates the token with the appropriate granted authorities "ROLE_user" and "ROLE_adminuser". Here's my config:
@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
X509AuthenticationFilter filter = new X509AuthenticationFilter()
filter.setAuthenticationManager(authenticationManager())
http.addFilterAfter(filter, SecurityContextPersistenceFilter.class)
http.authorizeRequests().anyRequest().permitAll()
}
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean()
X509AuthenticationFilter filter = new X509AuthenticationFilter()
filter.setAuthenticationManager(authenticationManager())
registrationBean.setFilter(filter)
registrationBean.setEnabled(false)
return registrationBean
}
I'm inserting the Filter before the SecurityContextPersistenceFilter as mentioned in: Spring security and custom AuthenticationFilter with Spring boot.
This seems to work fine, however, when I attempt to add a PreAuthorize annotation to my controller method, like so:
@Controller
@RequestMapping("/security")
class SecurityController {
@RequestMapping("/authenticate")
@PreAuthorize("hasRole('ROLE_user')")
@ResponseBody
ResponseEntity<String> authenticate(HttpServletRequest request, Principal principal) {
println "authenticate: " + SecurityContextHolder.getContext().getAuthentication()
return new ResponseEntity<String>(getPreAuthenticatedPrincipal(request), HttpStatus.OK)
}
I get a 404 error. If I comment out the PreAuthorize annotation the method call works and you can see that I print out the authentication information and the authenticated user has ROLE_user and ROLE_adminuser for its granted authorities. I'm not sure what I'm doing wrong.
Here's the print out of the authentication object in the principal when "PreAuthorize" is commented out:
authenticate: org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken@817a0240: Principal: org.springframework.security.ldap.userdetails.LdapUserDetailsImpl@c279eab8: Dn: uid=1,ou=people,dc=cdpe,dc=mil; Username: [email protected]; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; CredentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_adminuser, ROLE_user; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_adminuser, ROLE_user authorities: [ROLE_adminuser, ROLE_user]
Update: I've made a little progress. I added the proxyTargetClass to the following annotation:
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
Now I'm getting 403 Forbidden returns when I call my method. I have no idea what that is doing.
hasRole()
method accepts role withoutROLE_
prefix. So your check should be some think like this@PreAuthorize("hasRole('user')")
– Oleg Kuts