Java 使用@Secured注释保护MVC控制器方法

Java 使用@Secured注释保护MVC控制器方法,java,spring,spring-mvc,spring-security,Java,Spring,Spring Mvc,Spring Security,以下是我对使用SpringBoot制作的API的单一安全配置: @Configuration @EnableWebSecurity @EnableWebMvcSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserService userService; @Autowired private TokenAuthentic

以下是我对使用SpringBoot制作的API的单一安全配置:

@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());
    }

}
所有URL都映射到spring web mvc控制器,我想手动指定控制器及其方法的访问级别,如下所示:

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

    @Secured("ROLE_USER")
    some_method...
}
但是,当我以匿名用户身份执行/api/resource/*请求时,应用程序将以403状态代码响应,但我希望方法调用看起来@Secured annotation对授权没有影响,所有控制器方法只允许角色用户使用。

TokenAuthenticationFilter仅在存在令牌时才执行操作,因此我猜它没有效果

    @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);
}
更新:

考虑到这个问题下面的评论,我意识到@Secured注释是全局方法安全概念的一部分,而不是web安全的一般部分。现在我有以下权衡:

  • 使用@Secured注释并使方法访问级别信息分布在控制器类上,这可能导致在API增长的情况下难以确定fufture中的方法访问级别

  • 将所有方法访问信息保持在同一位置(配置),但必须支持@RequestMapping值与配置中的URL相等


  • 哪一个你会考虑最好的方法,或者告诉我如果我漏掉了什么东西?

    为了告诉Spring观看@安全的注释,在你的安全配置上你必须添加以下内容:

    @EnableGlobalMethodSecurity(securedEnabled = true)
    

    这是您在配置中指定的内容。。。对于所有URL,您都必须通过
    身份验证
    。那么我如何告诉Spring Security监视映射请求的任何其他控制器方法的注释?允许所有访问并使用全局方法安全性。URL和注释用于不同的用途。