【问题标题】:Secure MVC Controller methods with @Secured annotation使用 @Secured 注解保护 MVC 控制器方法
【发布时间】:2016-01-20 04:54:28
【问题描述】:

这是我使用 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 注解对授权没有影响,并且所有控制器方法只允许 ROLE_USER 使用。

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

更新:

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

  1. 使用@Secured 注解,方法访问级别信息分布在Controller 类中,这可能导致将来随着API 的增长难以确定方法访问级别。

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

您认为哪种方法最好,或者如果我遗漏了什么,请告诉我?

【问题讨论】:

  • 这是您在配置中指定的内容...对于所有网址,您必须是 authenticated
  • 那么我如何告诉 Spring Security 监视映射请求的任何其他控制器方法的注释?
  • 允许所有访问和使用全局方法安全性。 URL 和注释用于不同的事物。

标签: java spring spring-mvc spring-security


【解决方案1】:

为了告诉 Spring 监视 @Secured 注解,你必须在你的安全配置中添加以下内容:

@EnableGlobalMethodSecurity(securedEnabled = true)

【讨论】:

    猜你喜欢
    • 2016-10-18
    • 1970-01-01
    • 2015-01-28
    • 2018-01-10
    • 2015-09-04
    • 1970-01-01
    • 2012-01-29
    • 2015-01-16
    • 1970-01-01
    相关资源
    最近更新 更多