Spring Security 保护路由 hasRole,hasAuthority 不适用于 CORS http 请求

Posted

技术标签:

【中文标题】Spring Security 保护路由 hasRole,hasAuthority 不适用于 CORS http 请求【英文标题】:Spring Security protect routes hasRole, hasAuthority do not work with CORS http request 【发布时间】:2020-10-27 01:19:53 【问题描述】:

我正在使用Spring Security JWT 保护Angular 登录页面。 我将Spring CORS 过滤器配置为接受http CORS 请求。 我验证 JWT 作为回报是有效的,并使用正确的角色进行了身份验证。 hasRolehasAuthority 等安全路由在 CORS 请求上失败,总是返回 403 状态。

//http config
protected void configure(HttpSecurity http) throws Exception
  http.cors().and()
    .csrf().disable()
    .authorizeRequests()
    .antMatchers(HttpMethod.GET, "/api/list_customers").hasAnyRole("ADMIN","DEV") //FAIL 403 error
    .antMatchers(HttpMethod.GET, "/api/list_customers").hasAuthority("ROLE_ADMIN") //FAIL 403 error
    .anyRequest().authenticated()


//CORS filter
public class CORSFilter extends GenericFilterBean implements Filter 
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
            throws IOException, ServletException
            
        HttpServletResponse httpResp = (HttpServletResponse) response;  
        httpResp.setHeader("Access-Control-Allow-Origin",  "*");
        httpResp.setHeader("Access-Control-Allow-Methods", "*");
        httpResp.setHeader("Access-Control-Allow-Headers",  "*");
        httpResp.setHeader("Access-Control-Allow-Credentials",  "true");
        httpResp.setHeader("Access-Control-Max-Age", "3600");
        
        chain.doFilter(request, response);
    

【问题讨论】:

【参考方案1】:

删除您的过滤器并将其替换为

    @Bean
    CorsConfigurationSource corsConfigurationSource() 
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.addAllowedOrigin("*");
        configuration.addAllowedMethod("*");
        configuration.addAllowedHeader("*");
        configuration.setAllowCredentials(true);
        configuration.setMaxAge(3600l);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    
 

参考

org.springframework.web.filter.CorsFilter 获取战利品,看看它如何拾取CorsConfigurationSource bean 并配置 cors 过滤器

正如您在过滤器链中看到的那样,CorsFilter 在链中比过滤器更早地检查用户是否经过身份验证或他们是否具有正确的权限。 CorsFilter 更早地抛出了您的 403,因为它没有正确配置

【讨论】:

感谢您的建议 Kavithakaran,我也尝试了您的建议,但结果相同。没有一条安全路线有效。它返回 403。从 localhost 测试工作正常,但是当我部署到 github 时失败。【参考方案2】:

问题已解决。 我发现我的生产角色名称不同。 我将角色名称从 ADMIN 更改为 ROLE_ADMIN,然后它就可以正常工作了。

【讨论】:

以上是关于Spring Security 保护路由 hasRole,hasAuthority 不适用于 CORS http 请求的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security通配符路由绕过漏洞(CVE-2023-20860)

Spring starter security or spring cloud security 如何保护整个微服务架构?

Spring Security 配置:Basic Auth + Spring Cloud Gateway

使用 Spring Security 的 CSRF 保护

使用 Spring Security 的 CSRF 保护

使用 Spring Security 保护 REST API