【问题标题】:Tomcat 8 and Spring Security CorsTomcat 8 和 Spring Security Cors
【发布时间】:2020-02-26 17:18:16
【问题描述】:

我正在尝试配置 Spring Security 以使其支持 CORS。 感谢这篇文章 Spring security CORS Filter,我已经使用 Spring Boot 使用此配置代码在我的本地主机上运行它:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors()
        .and()
        .antMatcher("/api/**")
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .authorizeRequests()
        .antMatchers(HttpMethod.POST, "/api/login").permitAll()
        .antMatchers(HttpMethod.GET, "/api/websocket/**").permitAll()
        .antMatchers("/api/**").authenticated()
        .and()
        .addFilterBefore(new JWTLoginFilter("/api/login", HttpMethod.POST, authenticationManager(), tokenAuthenticationService, myUserService), UsernamePasswordAuthenticationFilter.class)
        .addFilterBefore(new JWTAuthenticationFilter(tokenAuthenticationService), UsernamePasswordAuthenticationFilter.class)
        .csrf().disable();
    }

@Bean
public CorsConfigurationSource corsConfigurationSource() {
    final CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(ImmutableList.of("*"));
    configuration.setAllowedMethods(ImmutableList.of("HEAD",
            "GET", "POST", "PUT", "DELETE", "PATCH"));
    // setAllowCredentials(true) is important, otherwise:
    // The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
    configuration.setAllowCredentials(true);
    // setAllowedHeaders is important! Without it, OPTIONS preflight request
    // will fail with 403 Invalid CORS request
    configuration.setAllowedHeaders(ImmutableList.of("Authorization", "Cache-Control", "Content-Type"));
    final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

}

但是当我在远程 Tomcat 服务器上部署我的应用程序时,它不起作用:

 Access to XMLHttpRequest at 'http://xxx:9080/yyy/api/user/findByLogin/?login=zzz' from origin 'http://xxx:10080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

这是失败的 OPTIONS 请求的屏幕截图:

我的本​​地主机上的工作请求:

我的配置类是否足够,或者我需要在 Tomcat 设置中进行设置吗? 谢谢

【问题讨论】:

  • 你能检查一下你的 OPTIONS 请求是否给出了 CORS 错误吗?如果是这样,请将其添加到您允许的方法中,然后重试。
  • OPTIONS 请求返回 403。我添加了屏幕截图。
  • 你能看看这篇文章吗? stackoverflow.com/questions/43699343/…
  • 同理,解决方案在本地有效,在Tomcat上无效。
  • 你的 pom.xml 和 main 类是什么样子的?请尝试提供minimal reproducible example

标签: java spring tomcat


【解决方案1】:

Spring security 提供了一种在 http 配置器中配置 CORS 的方法,有一种更简洁的方法可以将 CORS 过滤器添加到应用程序中-

@Component 
@Order(Ordered.HIGHEST_PRECEDENCE)
public class MyCORSFilterClass implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;

response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig filterConfig) {
}

@Override
public void destroy() {
}
}

以最高优先级排序过滤器确保 javax.servlet.Filter 的 MyCORSFilterClassimplementation 是链中的第一个。

【讨论】:

  • 使用过滤器,它可以在本地工作(如果你在 WebSecurityConfigurerAdapter 中添加 http.cors()),但仍然不能在我的 Tomcat 服务器上。
  • 对我来说同样的问题。任何解决方案@ClémentPicou?
【解决方案2】:

Tomcat 也有自己的 cors 过滤器,如果您在 tomcat 之前使用其他服务器(如 nodejs、apache 服务器 vs )也要检查它的 cors 过滤器。

【讨论】:

    【解决方案3】:

    检查 tomcat 服务器是否在 $CATALINA_BASE/conf/web.xml 中配置了冲突的 CORS 过滤器

    【讨论】:

      【解决方案4】:
      1. 尝试在本地的corsConfigurationSource() 方法中放置一个调试点并检查它是否正在执行。如果它没有被执行,请调查原因 - 可能通过启用 Spring 的调试日志和/或重新检查 Spring 配置。

      2. 另外,尝试将 OPTIONS 添加到 setAllowedMethods

        configuration.setAllowedMethods(ImmutableList.of("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
        

      【讨论】:

        【解决方案5】:
        1. 您的允许方法也应该有“OPTIONS”。
        2. 您是否拥有 Web 服务器?网络服务器是否也有 CORS?

        【讨论】:

          【解决方案6】:

          只需配置 CorsFilter 以使用提供的 CorsConfigurationSource 添加相关的 CORS 响应标头(如 Access-Control-Allow-Origin)。阅读其文档了解更多信息。由于您已经拥有UrlBasedCorsConfigurationSource,您可以将过滤器配置如下:

          @Bean
            public FilterRegistrationBean corsFilter() {
              FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(corsConfigurationSource()));
              bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
              return bean;
            }
          

          只要在你的配置中加入上面提到的 bean,希望它可以工作。

          这是我的完整配置,您只需要上面提到的一部分:

          @Bean
            public FilterRegistrationBean corsFilter() {
              UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
              CorsConfiguration config = new CorsConfiguration();
              config.setAllowCredentials(true);
              config.addAllowedOrigin("*");
              config.addAllowedHeader("*");
              config.addAllowedMethod("*");
              config.addExposedHeader("Content-Disposition");
              source.registerCorsConfiguration("/**", config);
              FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
              bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
              return bean;
            }
          

          【讨论】:

            【解决方案7】:

            响应 403 反映了授权失败。可能是您的服务器设置为请求选项请求的授权。您必须确保将选项配置为发送成功响应(2xx 状态代码)以允许浏览器发送实际请求。 2xx 响应通知浏览器服务器处理 CORS 请求。

            您的请求在本地有效的原因可能是您在提出请求时获得了授权。因此,请检查您的身份验证以确保其正确。因此,飞行前请求不会发送任何授权标头,因此您不应期望在服务器端。

            【讨论】:

              猜你喜欢
              • 2015-10-13
              • 2016-06-29
              • 2019-07-16
              • 2017-03-02
              • 2016-10-23
              • 2019-06-11
              • 2017-09-09
              • 2014-04-07
              相关资源
              最近更新 更多