Tomcat CORS 过滤器和 Spring Security

Posted

技术标签:

【中文标题】Tomcat CORS 过滤器和 Spring Security【英文标题】:Tomcat CORS filter and Spring Security 【发布时间】:2015-10-13 15:40:25 【问题描述】:

我使用的是 Tomcat 7。我已按照 Tomcat 官方文档中的建议设置了本机 CORS 过滤。

我已经尽我所能测试了,但它不起作用。鉴于我正在使用我知道正在使用 Spring Security 过滤器的供应商应用程序,我想知道这里是否存在已知错误。

这就是我要说的:

<!-- Spring Security START -->
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/</url-pattern>
</filter-mapping>
<!-- Spring Security END -->

我在 Web.xml 中添加了以下配置:

<filter>
    <filter-name>CorsFilter</filter-name>
    <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>CorsFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

我知道它是最小的,但它应该可以工作。

我之前也尝试过更长的版本:

<filter>
    <filter-name>CorsFilter</filter-name>
    <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
    <init-param>
        <param-name>cors.allowed.origins</param-name>
        <param-value>*</param-value>
    </init-param>
    <init-param>
        <param-name>cors.allowed.methods</param-name>
        <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
    </init-param>
    <init-param>
        <param-name>cors.allowed.headers</param-name>
        <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
    </init-param>
    <init-param>
        <param-name>cors.exposed.headers</param-name>
        <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
    </init-param>
    <init-param>
        <param-name>cors.support.credentials</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>cors.preflight.maxage</param-name>
        <param-value>10</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CorsFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

它也没有工作。

有人有使用 Spring Security 设置 CORS 过滤器的经验吗?

【问题讨论】:

您能否更具体地说明“它不起作用”? 您的确切 tomcat 版本是多少? 您是否尝试将 cors 过滤器放在弹簧过滤器之前? 【参考方案1】:

我有类似的配置,关键问题是 Authorization 标头在 Tomcat 的默认值中是不允许的 cors.allowed.headers 初始化参数。所以我只需要像这样添加它:

<filter>
    <filter-name>CorsFilter</filter-name>
    <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
    <init-param>
        <param-name>cors.allowed.headers</param-name>
        <param-value>Authorization,Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
        <!--         ^^^^^^^^^^^^^ -->
    </init-param>
</filter>

【讨论】:

【参考方案2】:

您的供应商应用程序必须启用以使用适当的 CORS 标头响应传入的预检选项请求。这不是一个错误,它只是为 Spring 启用 CORS 所缺少的配置和/或一些代码行。启用 CORS 对您的供应商来说没什么大不了的,但它可能对您来说很重要,特别是如果您在 eclipse 中没有应用程序 java 项目的副本。

如果幸运的话,您的供应商应用程序已经在 Spring Framework 4.2 RC2 上运行,您可以自己在 XML 中进行配置,请参阅https://spring.io/blog/2015/06/08/cors-support-in-spring-framework。 只需尝试将 &lt;mvc:cors&gt; 块添加到您的应用程序 web.xml 并根据您的需要配置值。我还没有自己测试过,但它应该可以解决问题。

但我担心你可能没有那么幸运......

如果您不想让供应商更新应用程序/您的 WAR 文件,事情就会变得有点棘手。 在这种情况下,请查看此帖子:Can't set Authentication Header with Angular and Spring Security。帖子中的答案描述了需要在您的应用程序的web.xml 中完成的配置(创建一个新的 CORS 过滤器并将其绑定到您必须创建的类)以及附加的 java过滤器类(在示例中,该类在包com.abcinsights.controller 中被命名为SimpleCorsFilter 必须看起来使它工作。要将新的 java 类添加到您的应用程序中,您必须解包 WAR,创建并添加新的 java 过滤器类(不要忘记新 java 类中的包声明)并重新打包它。这是最复杂的部分,因为如果您在类中或重新打包过程中犯了错误,您可能会在重新部署后第一次看到错误。

【讨论】:

【参考方案3】:

我可能错了。但是我见过的每个配置文件的参数名称都与您的不同,也许这就是问题所在,我一直看到和做的是:

<filter>
    <filter-name>CorsFilter</filter-name>
    <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
    <init-param>
        <param-name>cors.allowOrigin</param-name>
        <param-value>*</param-value>
    </init-param>
    <init-param>
        <param-name>cors.supportedMethods</param-name>
        <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
    </init-param>
    <init-param>
        <param-name>cors.supportedHeaders</param-name>
        <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
    </init-param>
    <init-param>
        <param-name>cors.exposedHeaders</param-name>
        <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
    </init-param>
    <init-param>
        <param-name>cors.supportsCredentials</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>cors.maxAge</param-name>
        <param-value>10</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CorsFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

【讨论】:

【参考方案4】:

您必须在 web.xml 中的 Spring Security Filter 之前添加 CORS 过滤器

CORS OPTIONS HTTP 请求不需要由 Spring Security 处理

【讨论】:

嗯,Mourad 是对的。在高层次上,这是必须要做的。

以上是关于Tomcat CORS 过滤器和 Spring Security的主要内容,如果未能解决你的问题,请参考以下文章

Tomcat 8 和 Spring Security Cors

使用 Spring MVC 为所有 API 启用 CORS

如何启用 CORS tomcat 8.5 过滤器来访问静态文件?

带有Angular应用程序的tomcat 9服务器上的Spring Boot 404和CORS

严重:异常启动过滤器 CORS

使用 Spring Boot、Apache 和 Tomcat 在客户端/服务器系统中配置 CORS