身份验证过滤器之前的 CORS 过滤器 - 不太安全? Spring Security 过滤器链序

Posted

技术标签:

【中文标题】身份验证过滤器之前的 CORS 过滤器 - 不太安全? Spring Security 过滤器链序【英文标题】:CORS Filter before Authentication Filter - is less secure? Spring Security Filter Chain Order 【发布时间】:2016-06-27 10:51:17 【问题描述】:

我发现在从单页应用程序访问 ReST 服务时,为了正确允许访问 ReST 端点,我必须在身份验证过滤器之前注册一个 CORS 过滤器。这是安全性较低还是安全性较差?

我的安全配置现在看起来像

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter 

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception 
        return super.authenticationManagerBean();
    

    @Inject
    public void setUserDetailsService(UserDetailsService userDetailsService) 
        this.userDetailsService = userDetailsService;
    

    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception 
        authenticationManagerBuilder.userDetailsService(userDetailsService)
                .passwordEncoder(new BCryptPasswordEncoder());
    

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception 
        httpSecurity
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
           .authorizeRequests()
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                .antMatchers("/health","/metrics", "/v1/users/register", "/swagger-ui/**", "/v2/api-docs").permitAll()
                .antMatchers("/mappings", "/v1/**", "/backend-service/**").authenticated()
                .and()
            .httpBasic()
                .realmName("serviceGateway")
                .and()
            .csrf()
                .disable()
            .headers()
                .frameOptions().disable()
            .and().addFilterBefore(new SimpleCORSFilter(), ChannelProcessingFilter.class);
    


我的 SimpleCORSFilter 看起来像

public class SimpleCORSFilter implements Filter 

    @Override
    public void init(FilterConfig filterConfig) throws ServletException 

    

    /**
     * This method adds specific headers to the HTTP request to enable CORS
     * requests
     * @param request
     * @param response
     * @param chain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException 
        HttpServletResponse res = (HttpServletResponse) response;
        res.setHeader("Access-Control-Allow-Origin", "*");
        res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        res.setHeader("Access-Control-Max-Age", "3600");
        res.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept, x-requested-with, Cache-Control");
        chain.doFilter(request, res);
    

    @Override
    public void destroy() 

    

我在 Angular 中通过一个简单的 $http 调用来访问代码

$scope.login = function() 
  $http(
    method: 'GET',
    url: 'https://myservice.mydomain.com:8095/v1/users/login',
    headers: 
      'Authorization': 'Basic ' + btoa("username:password")
    
  )
    .then(successCallback);
;

我认为将 CORS 过滤器放在安全性之前仅意味着 CORS 标头将添加到每个请求中,这似乎不是一个安全漏洞,因为我在标头中不发送任何敏感数据,授权标头除外.

我是在这里思考还是有什么我没有看到?

【问题讨论】:

【参考方案1】:

我认为这很好。实际上,当您的 javascript 代码发布到另一个来源的资源时,浏览器将发出一个预飞行请求(OPTIONS 动词),而没有 authorization 标头。

如果您的身份验证代码在 CORS 处理程序之前运行,它必须对此请求进行异常处理,以避免在飞行前返回 401 Unauthorized

【讨论】:

以上是关于身份验证过滤器之前的 CORS 过滤器 - 不太安全? Spring Security 过滤器链序的主要内容,如果未能解决你的问题,请参考以下文章

Pentaho CDA:基本身份验证和 CORS 冲突

具有基本身份验证的 Jersey cors 不起作用

使用 Angular 和 spring 进行 Jwt 身份验证

如何在身份验证之后和注销之前调用方法? (春季安全)

InsufficientAuthenticationException:访问此资源需要完全身份验证

添加 CORS 过滤器后未找到 Access-Control-Allow-Origin 标头