【问题标题】:Spring Security CORS call to spring removes headers from the requestSpring Security CORS 对 spring 的调用从请求中删除标头
【发布时间】:2019-08-05 00:42:10
【问题描述】:

我有一个 spring boot + spring security 应用程序,我允许 CORS(跨域)调用该应用程序。

我定义了以下 spring 安全配置,

http
            .authorizeRequests()
                .antMatchers( "/transaction/**").hasRole(SOME_ROLES)
                .antMatchers( "/", "/anonymous/pay").permitAll()
                .anyRequest().authenticated()
            .and()
                .csrf().disable()
            .addFilterBefore(new StatelessLoginFilter(LOGIN_FILTER_URL, tokenAuthenticationService, authenticationManager()), UsernamePasswordAuthenticationFilter.class)
            .addFilterBefore(new StatelessAuthenticationFilter(tokenAuthenticationService), UsernamePasswordAuthenticationFilter.class)
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).maximumSessions(1);

并且我在CORS下面添加了配置,

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {

        registry.addMapping("/anonymous/pay")
            .allowedOrigins("http://mydomain:8080")
            .allowedMethods("PUT", "DELETE", "OPTIONS")
            .allowedHeaders("header1", "header2", "header3")
            .exposedHeaders("header1", "header2")
            .allowCredentials(true).maxAge(3600);

        // Add more mappings...
    }
}

问题:

当从不同来源(跨源)在http://mydomain:8080/anonymous/pay 上发送请求时,过滤器仍会被调用,而且没有发送到实际/pay 调用的标头。请注意,在发送实际请求之前,Chrome 会向服务器发送 OPTIONS 调用。但是在实际请求中发送的/pay 中缺少标头。一旦触发StatelessAuthenticationFilter,HTTP 请求就不会携带在/pay 调用中发送的headers。

有什么见解吗?

【问题讨论】:

  • 显示带有OPTIONS 调用和实际调用标头的请求和响应。例如浏览器中开发工具的屏幕截图 (F12)。

标签: spring-boot spring-mvc spring-security http-headers cross-domain


【解决方案1】:

最近遇到了这个问题,找到了解决办法。

当您发送跨域请求时会发生什么,在我使用浏览器的情况下,'preflight' 请求被发送到相同的 URL,但使用 OPTIONAL http 方法和一些标头(不包括您添加的那些,因此它们丢失了)。

您的 Spring Security 配置拒绝对此预检请求的授权,因为它已以这种方式设置(当然是无意的)并且您收到 403 响应。

这已经被here 讨论为一个问题,我通过chuan-su 找到了this solution。

[编辑] 找到了Robert Schmidt 提出的 SO 问题,他发起了上面链接的讨论。

基本上,您必须在 spring 安全配置中将 cors().and() 链接到 http 并像这样更改 CORS 配置

@Override
public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**")
        .allowedOrigins("*") //possibly redundant
        .allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH")
             // which ever methods you will be using
        .allowedHeaders("Authorization", "Cache-Control", "Content-Type")
            // headers that you will be adding to your requests
        .allowCredentials(true);
}

如果您通过注入 CorsConfigurationSource @Bean 来配置 CORS,chuan-su 在他的解决方案中提到了它的设置以及上面给出的方法。请看链接。

[EDIT] 链接到另一个答案,即根据帖子本身的 cleaner 方法。虽然没有尝试过,但似乎可以工作。

【讨论】:

    猜你喜欢
    • 2020-05-01
    • 2018-08-19
    • 2020-09-01
    • 2020-06-30
    • 2016-04-11
    • 2019-12-26
    • 2016-06-25
    • 2022-11-21
    • 2021-02-10
    相关资源
    最近更新 更多