java - 使用@Secured 注释保护 MVC Controller 方法

标签 java spring spring-mvc spring-security

这是我使用 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 Controller ,我想像这样手动指定 Controller 及其方法的访问级别:

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

    @Secured("ROLE_USER")
    some_method...
}

但是当我以匿名用户身份执行/api/resource/* 请求时,应用程序会以 403 状态代码响应,但我希望调用方法。 @Secured 注释似乎对授权没有影响,并且所有 Controller 方法仅允许 ROLE_USER。

TokenAuthenticationFilter 仅在 token 存在时才执行操作,所以我猜它没有任何效果。

    @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 注释是全局方法安全概念的一部分,而不是网络安全的一般部分。现在我有以下权衡:

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

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

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

最佳答案

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

@EnableGlobalMethodSecurity(securedEnabled = true)

关于java - 使用@Secured 注释保护 MVC Controller 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33255149/

相关文章:

java - 在数组列表中将特定单词连接在一起

java - 我无法在jsp页面中包含css文件

java - Spring MessageSource 通过多个语言环境查找

java - 错误 - 在 Eclipse 中使用 Tomcat 服务器和 Spring MVC 框架的 Web 项目

java - 如何在邮件正文中发送图像而不是像java中的附件一样

java - 根据JAVA中先前的拆分重新组装拆分字符串?

java - 跨不同 JVM 的相同 SparkContext

java - spring data jpa复合键重复键记录插入导致更新

java - Spring Security 3.2 Java配置

java - Spring中的自定义json