PreAuthorize and Custom AuthenticationFilter with Spring Boot

I have my own authentication filter that creates a PreAuthenticatedAuthenticationToken and stores it in a security context. The filter works fine, it creates a token with the appropriate authority "ROLE_user" and "ROLE_adminuser". Here is my configuration:

@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 insert a filter in front of SecurityContextPersistenceFilter, as stated in: Spring Security and a custom AuthenticationFilter with Spring loading .

This works fine, however, when I try to add the PreAuthorize annotation to my controller method, for example:

 @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 error 404. If I comment on the PreAuthorize annotation, the method call works, and you can see that I am printing out the authentication information and the authenticated user has ROLE_user and ROLE_adminuser for the privileges granted. I'm not sure what I'm doing wrong.

This prints out the authentication object in the directory when "PreAuthorize" is commented out:

Authentication: org.springframework.security .web.authentication.preauth.PreAuthenticatedAuthenticationToken@ 817a0240: Basic: or g.springframework.security.ldap.userdetails.LdapUserDetailsImpl@ c279eab8: Dn: uid = 1, ou = people, dc = cdpe, dc = mil; Username: xxxx@gmail.com ; Password Protected]; Enabled: true; AccountNonExpired: true; CredentialsNonExpired: true; AccountNonLocked: true; Provided by the Authority: ROLE_adminuser, ROLE_user; Credentials: [PROTECTION]; Authenticated: true; Details: org.sprin gframework.security.web.authentication.WebAuthenticationDetails@ 957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Authority granted: ROLE_adminuser, authority ROLE_user: [ROLE_adminuser, ROLE_user]

Update: I am a little advanced. I added proxyTargetClass to the following annotation:

  @EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true) 

Now I get 403 Forbidden returns when I call my method. I have no idea what this does.

+6
source share
2 answers

Hmm, Spring Security will always be tedious to configure, and the only fooproof ways are:

  • either be an expert on the subject, but also be prepared to look at the sources, and then you can do heavy things manually.
  • or use as much as possible of what is provided by the framework, using examples from the documentation whenever possible

For the X509AuthenticationFilter configuration, the HttpSecurity javadoc gives the x509 method x509 following example (adapted to your configuration - see javadoc for the original):

 @Configuration @EnableWebMvcSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests().anyRequest().permitAll() // Example x509() configuration .x509(); } } 

with the following indication: the method returns X509Configurer for further settings.

Unless you have a good reason to act differently (and if so, tell me about it), I strongly recommend that you follow this method.

But actually it’s nice to use annotation before publishing to the controller, which can be done directly in the HttpSecurity configuration. This made you use proxyTargetClass = true .

Preliminary and post annotations are usually applied to service level methods, which does not require proxyTargetClass=true , because services are usually connected to the controller through interfaces that allow JDK proxing.

+7
source

Thank you for your help. In this example, I am forced to reuse an existing Spring Security Filter. I'm just trying to get it working in the context of spring-boot.

Adding Targetclass = true proxy to the above code seems to fix the problem.

0
source

Source: https://habr.com/ru/post/985606/


All Articles