Protected MVC controller methods using @Secured annotations

Here is my only security configuration for the API created using SpringBoot:

@Configuration @EnableWebSecurity @EnableWebMvcSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserService userService; @Autowired private TokenAuthenticationService tokenAuthenticationService; @Override protected void configure(HttpSecurity http) throws Exception { http .csrf().disable() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .authorizeRequests() .antMatchers("/").permitAll() .antMatchers("/static/**").permitAll() .antMatchers(HttpMethod.POST, "/api/user/registration").permitAll() .antMatchers(HttpMethod.POST, "/api/user/authentication").permitAll() .anyRequest().authenticated().and() .addFilterBefore(new TokenLoginFilter("/api/user/authentication", authenticationManagerBean(), tokenAuthenticationService), UsernamePasswordAuthenticationFilter.class) .addFilterBefore(new TokenAuthenticationFilter(tokenAuthenticationService),UsernamePasswordAuthenticationFilter.class); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder()); } } 

All URLs map to spring web mvc controllers, and I would like to manually specify the access levels for the controllers and their methods as follows:

 @RestController @RequestMapping("/api/resource/") @Secured("ROLE_ANONYMOUS") //as default role public class ResourceController { ... @Secured("ROLE_USER") some_method... } 

But when I execute the request / api / resource / * as an anonymous user, the application answers with the status code 403, but I expect the method to call. It seems that the @Secured annotation does not affect authorization, and all controller methods are allowed only for ROLE_USER.

The TokenAuthenticationFilter function only performs an action if a token is present, so I think this has no effect.

  @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpServletRequest = (HttpServletRequest) req; String token = httpServletRequest.getHeader(TokenAuthenticationService.AUTH_HEADER_NAME); if (token != null) { try { SecurityContextHolder.getContext() .setAuthentication(tokenAuthenticationService.verifyToken(new TokenAuthentication(token))); } catch (AuthenticationException e) { ((HttpServletResponse) res).setStatus(HttpServletResponse.SC_UNAUTHORIZED); return; } } chain.doFilter(req, res); } 

Update:

Given the comments below this question, I realized that the @Secured annotation is part of the concept of a global security concept, and not in general regarding website security. Now I have the following tradeoff:

  • Use the @Secured annotation and have method access information distributed across controller classes, which can lead to a situation where the level of access to the diffusion detection method in fufture is growing using the API.

  • Store all method access information in the same place (config), but must maintain @RequestMapping values ​​equal to the URLs in config.

Which one do you think is the best approach, or please tell me if I missed something?

+5
source share
1 answer

To tell Spring to view the @Secured annotation, in your Security Config you must add the following:

 @EnableGlobalMethodSecurity(securedEnabled = true) 
+2
source

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


All Articles