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?