使用 Spring Security 启用 CORS 支持所需的 FilterRegistrationBean?

Posted

技术标签:

【中文标题】使用 Spring Security 启用 CORS 支持所需的 FilterRegistrationBean?【英文标题】:FilterRegistrationBean necessary to enable CORS support with Spring Security? 【发布时间】:2018-08-31 15:23:00 【问题描述】:

我的资源服务器受 OAuth2 保护并使用此 CORS 配置:

@Bean
CorsConfigurationSource corsConfigurationSource()

    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowCredentials(true);
    configuration.setAllowedOrigins(Arrays.asList("*"));
    configuration.setAllowedMethods(Arrays.asList("*"));
    configuration.setAllowedHeaders(Arrays.asList("*"));

    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;


@Bean
FilterRegistrationBean<CorsFilter> corsFilter(CorsConfigurationSource corsConfigurationSource)

    CorsFilter corsFilter = new CorsFilter(corsConfigurationSource);

    FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>();
    bean.setFilter(corsFilter);
    bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    return bean;

配置按预期处理预检请求,但我想知道为什么有必要创建自定义 FilterRegistrationBean 并设置其顺序,而不是使用 HttpSecurity.cors() 记录的 here 的官方 CORS 支持:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter

    @Override
    protected void configure(HttpSecurity http) throws Exception
    
        http.cors();
    

    @Bean
    CorsConfigurationSource corsConfigurationSource()
    
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowCredentials(true);
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("*"));
        configuration.setAllowedHeaders(Arrays.asList("*"));

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    

上述配置不能正确处理预检请求,我猜 CORS 过滤器的优先级低于 spring 安全过滤器。

使用第一个 FilterRegistrationBean 版本是否有缺点,或者为什么官方的 cors 配置不能正常工作?是不是我配置官方的方式出错了?

我正在使用带有 spring-security-oauth2-autoconfigure 的 Spring Boot 2,但在 Spring Boot 1.5.x 中得到了相同的行为。

【问题讨论】:

@dur 谢谢你的评论。你是对的,我使用了 100 的默认顺序,改变它会导致预期的行为。如果你喜欢写一个答案,我会接受。您对特定订单价值有什么建议吗?或者Ordered.HIGHEST_PRECEDENCE 是要走的路吗? 刚刚找到here的信息:EnableResourceServer注解创建了一个硬编码Order为3的WebSecurityConfigurerAdapter,猜下面的任何值都可以。 【参考方案1】:

您的WebSecurityConfig 类永远不会用于任何请求,因为默认顺序是 100,请参阅WebSecurityConfigurerAdapter

@Order(value=100)
public abstract class WebSecurityConfigurerAdapter
extends java.lang.Object
implements WebSecurityConfigurer<WebSecurity>

并且资源服务器配置的默认顺序是3,见EnableResourceServer

注释使用硬编码的Order(共 3 个)创建一个 WebSecurityConfigurerAdapter

如果您想使用 WebSecurityConfig 类,您必须将顺序更改为小于 3 的值。但要小心,因为您可能会隐藏您的资源服务器配置。

如果您的应用程序也是授权服务器,那么您也必须小心。无法使用带有 EnableAuthorizationServer 注释的授权服务器配置。授权服务器的安全配置默认顺序为0,见AuthorizationServerSecurityConfiguration

如果您只想在资源服务器配置中添加 CORS 支持,则覆盖 ResourceServerConfigurerAdapter#configure(HttpSecurity http) 会更容易。

【讨论】:

以上是关于使用 Spring Security 启用 CORS 支持所需的 FilterRegistrationBean?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Spring MVC 和 Spring Security 为资源处理程序启用 HTTP 缓存

如何使用 XML 使用 Spring Security Oauth2 启用 /oauth/check_token

如何解决在使用 Spring Boot 和 Spring Security 启用 CSRF 后无法正常工作的登录问题?

使用 Spring Security 启用对 @RestController 的访问

使用 Spring Security 启用 CORS 支持所需的 FilterRegistrationBean?

使用邮递员测试启用 Spring Security 的 API