【问题标题】:Pre-flight request is authenticated even if CorsFilter is enabled in Spring Boot即使在 Spring Boot 中启用了 CorsFilter,也会对飞行前请求进行身份验证
【发布时间】:2020-02-21 07:12:02
【问题描述】:

我正在使用 Spring Security 进行 OAuth 身份验证,并且我已经配置了 Cors。但是,我的所有预检请求由于身份验证而失败,因为预检请求没有令牌(应该是这样)。我有以下配置类;

SecurityConfiguration.java

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(final HttpSecurity security) throws Exception {

        security.cors()
                .and()
                .requestMatchers()
                .antMatchers("/actuator/health")
                .and()
                .authorizeRequests()
                .antMatchers("/actuator/health").permitAll()
                .and()
                .csrf().disable();

        // Custom filter to validate if user is authorized and active to access the system
        security.addFilterAfter(new AuthorizationFilter(), BasicAuthenticationFilter.class);
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration().applyPermitDefaultValues();
        configuration.setAllowedMethods(Arrays.asList("GET","HEAD","POST","PUT"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

WebMvcConfiguration .java

@Configuration
public; class WebMvcConfiguration implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedMethods("GET","HEAD","POST","PUT");
    }
}

问题:

  1. 为什么即使我启用了 CorsFilter,预检请求也会进入身份验证?
  2. 如何排除预检请求以进行身份​​验证?

更新:

我在 application.yml 文件中使用 logging.level.org.springframework.security.web.FilterChainProxy: DEBUG 启用了调试问题的日志。

我获取了过滤器链中注册的过滤器列表,列表如下:

class org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter
class org.springframework.security.web.context.SecurityContextPersistenceFilter
class org.springframework.security.web.header.HeaderWriterFilter
class org.springframework.web.filter.CorsFilter
class org.springframework.security.web.authentication.logout.LogoutFilter
class org.springframework.security.web.savedrequest.RequestCacheAwareFilter
class org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter
class org.springframework.security.web.authentication.AnonymousAuthenticationFilter
class org.springframework.security.web.session.SessionManagementFilter
class org.springframework.security.web.access.ExceptionTranslationFilter
class org.springframework.security.web.access.intercept.FilterSecurityInterceptor
class org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter

注意 corsFilter 已注册。但是,当我收到请求时,只有以下过滤器正在运行,而不是 CorsFilter;

'WebAsyncManagerIntegrationFilter'
'SecurityContextPersistenceFilter'
'HeaderWriterFilter'
'LogoutFilter'
'BearerTokenAuthenticationFilter'
'RequestCacheAwareFilter'
'SecurityContextHolderAwareRequestFilter'
'AnonymousAuthenticationFilter'
'SessionManagementFilter'
'ExceptionTranslationFilter'
'FilterSecurityInterceptor'

更新 2:

在测试时,我注意到“/actuator/health”正在调用 CorsFilter。但我不确定这是什么意思?

【问题讨论】:

  • 你不允许OPTION方法
  • 我必须显式添加OPTIONS 方法吗?不是自动添加的吗?
  • @DarrenForsythe 即使对于其他请求(GET、POST、PUT),它也不会调用 cors 过滤器。

标签: spring spring-boot cors spring-security-oauth2


【解决方案1】:

将以下内容添加到您的配置 security.cors() 应该启用了 CORS 过滤器,该过滤器应该使飞行前请求在没有授权令牌的情况下工作。但您似乎错误地配置了您的请求机器,请使用正确的 url 映射所以安全配置将应用于所有端点。

另外,尝试设置您允许的来源以覆盖所有来源:

@Bean
CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration().applyPermitDefaultValues();
    configuration.setAllowedMethods(Arrays.asList("GET","HEAD","POST","PUT"));
    configuration.setAllowedOrigins(Arrays.asList("*"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

指南:https://www.baeldung.com/spring-security-multiple-entry-points

【讨论】:

  • 我已经添加了security.cors() 并对来源进行了更改。尽管如此,除了"/actuator/health" 之外,CorsFilter 并没有被调用
  • 你能不能去掉requestMatchers() 条目,让springboot默认工作。现在您只配置了端点 /actuator/health 以使其正常工作。
  • 如果我删除 requestMatchers() 则不会触发身份验证。
  • 您使用的当前配置仅匹配端点 /actuator/endpoint。请仔细阅读文档以了解每种方法所代表的含义并重新配置它。
  • 只使用 http.authorizeRequests().antMatchers("/**") 来匹配所有请求。
猜你喜欢
  • 1970-01-01
  • 2018-08-29
  • 2023-03-19
  • 1970-01-01
  • 2015-11-22
  • 2018-02-08
  • 2019-02-08
  • 2019-05-29
  • 1970-01-01
相关资源
最近更新 更多