首页 文章

Zuul Proxy CORS头包含多个值,头重复两次 - Java Spring Boot CORS过滤器配置

提问于
浏览
3

为什么我会将每个CORS标头加倍?我正在使用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标头重复了两次:
CORS Headers repeated

所以这看起来像我的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);
    }

}

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

2 回答

  • 9

    我也有同样的问题,我将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,它的工作原理!

  • 2

    我有类似的问题,但问题是我在APIGateway和其他服务中都有CORS过滤器 . 如果不是你的情况那么试试这个CORS过滤器 .

    将其添加到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);
    }
    

相关问题