Zuul Proxy CORS header 包含多个值,headers 重复两次 - Java Spring Boot CORS filter config

Zuul Proxy CORS header contains multiple values, headers repeated twice - Java Spring Boot CORS filter config

为什么每个 CORS header 都会翻倍?我正在使用 Zuul 代理来请求通过 API 网关代理的服务。

我的 spring 安全过滤命令一定是配置有误。

当我访问需要身份验证的路由时,出现如下错误:

通过API 网关错误请求服务

XMLHttpRequest cannot load https://myservice.mydomain.com:8095/service/v1/account/txHistory?acctId=0.  
The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed. 
Origin 'http://localhost:9000' is therefore not allowed access.

Chrome网络日志

我检查了 Chrome devtools 中的响应,果然 CORS headers 重复了两次:

所以这看起来像是我的 CORS 过滤器在每次回复时都被调用了两次。我不知道为什么会在此时发生。可能是我的过滤器添加在 ChannelProcessingFilter 之前。

API 网关 CORS 过滤器的代码:

public class SimpleCORSFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse res = (HttpServletResponse) response;
        res.setHeader("Access-Control-Allow-Origin", "*");
        res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        res.setHeader("Access-Control-Max-Age", "3600");
        res.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept, x-requested-with, Cache-Control");
        chain.doFilter(request, res);
    }

    @Override
    public void destroy() {}
}

我的API网关安全配置:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Inject
    public void setUserDetailsService(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
        authenticationManagerBuilder.userDetailsService(userDetailsService)
                .passwordEncoder(new BCryptPasswordEncoder());
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
           .authorizeRequests()
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                .antMatchers("/health","/metrics", "/v1/users/register").permitAll()
                .antMatchers("/mappings", "/v1/**", "/service/**").authenticated()
                .and()
            .httpBasic()
                .realmName("apiRealm")
                .and()
            .csrf()
                .disable()
            .headers()
                .frameOptions().disable()
            .and().addFilterBefore(new SimpleCORSFilter(), ChannelProcessingFilter.class);
    }

}

我可以通过检查 header 是否为 null 然后仅在它为空或 null 时设置它来解决这个问题,尽管这似乎不是最佳解决方案。我想了解我做了什么导致 headers 被预设两次。

我遇到了类似的问题,但问题是我在 API 网关和其他服务中都有 CORS 过滤器。如果那不是你的情况,那么试试这个 CORS 过滤器。

将此添加到 class 中您在 API 网关中有 @EnableZuulProxy 的地方。这应该可以解决问题,我的配置也类似。

@Bean
public CorsFilter corsFilter() {
    final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    final CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");
    config.addAllowedHeader("*");
    config.addAllowedMethod("OPTIONS");
    config.addAllowedMethod("HEAD");
    config.addAllowedMethod("GET");
    config.addAllowedMethod("PUT");
    config.addAllowedMethod("POST");
    config.addAllowedMethod("DELETE");
    config.addAllowedMethod("PATCH");
    source.registerCorsConfiguration("/**", config);
    return new CorsFilter(source);
}

我也遇到了同样的问题,我在class中添加了CorsFilter,其中有@EnableZuulProxy,但仍然没有解决我的问题。

根据 github Q&A Zuul Access-Control-* Headers are duplicated

zuul.ignored-headers=Access-Control-Allow-Credentials, Access-Control-Allow-Origin

将它添加到我的 zuul bootstrap.properties,它有效!!!

对我来说,这个解决方案可以解决 zuul 中的 CORS 问题。

endpoints.cors.allowed-origins=*
endpoints.cors.allowed-headers=*
endpoints.cors.allowed-methods=*

但是,这在我的一个暂存环境中似乎对我不起作用。

我通过在云网关中添加过滤器来修复:

spring: 云:
网关: default-filters: - DedupeResponseHeader=Access-Control-Allow-Origin Access-Control-Allow-Credentials, RETAIN_UNIQUE

感谢https://lifesaver.codes/answer/doubled-cors-headers-after-upgrade-to-greenwich-728