You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker部署Keycloak搭配Spring Cloud Gateway出现Swagger CORS错误

解决Spring Cloud Gateway + Keycloak环境下Swagger UI的CORS问题

核心问题拆解

你的场景里CORS问题和三个关键点强相关:

  1. 浏览器将localhost和127.0.0.1视为完全不同的源,Keycloak和Gateway的跨域配置必须同时覆盖这两个地址
  2. 400错误本质是Keycloak收到的授权请求中,源地址或重定向URI不匹配客户端配置,触发参数校验失败
  3. Spring Cloud Gateway的CORS过滤器执行顺序可能晚于Security拦截器,导致配置不生效

具体解决步骤

1. 修正Keycloak客户端配置

  • 打开Keycloak控制台,找到对应客户端的Web Origins配置:
    • 直接填入+(允许所有与Valid Redirect URIs匹配的源,本地开发最省心)
    • 或者明确添加:http://localhost:8080、http://127.0.0.1:8080、http://localhost:8080/*、http://127.0.0.1:8080/*
  • 同步更新Valid Redirect URIs,确保包含http://localhost:8080/*和http://127.0.0.1:8080/*
  • 注意:不要填*,会和allowCredentials冲突,导致浏览器拒绝跨域请求

2. 调整Spring Cloud Gateway的CORS与Security配置

全局CORS配置必须整合到Security链中,确保CORS过滤器先于Security拦截执行:

@Configuration
@EnableWebFluxSecurity
public class GatewaySecurityConfig {
    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        http
            // 优先配置CORS
            .cors(cors -> cors.configurationSource(corsConfigurationSource()))
            .authorizeExchange(exchanges -> exchanges
                // 明确放行Swagger全路径
                .pathMatchers("/webjars/**", "/swagger-ui/**", "/v3/api-docs/**", "/swagger-resources/**")
                .permitAll()
                .anyExchange().authenticated()
            )
            .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()));
        return http.build();
    }

    private CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        // 允许本地两个源
        config.addAllowedOrigin("http://localhost:8080");
        config.addAllowedOrigin("http://127.0.0.1:8080");
        // 允许所有请求方法
        config.addAllowedMethod("*");
        // 允许所有请求头(包括Keycloak授权头)
        config.addAllowedHeader("*");
        // 允许携带凭证(Cookie、Authorization等)
        config.setAllowCredentials(true);
        // 暴露Swagger需要的响应头
        config.addExposedHeader("Content-Type");
        config.addExposedHeader("Authorization");

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return source;
    }
}
  • 删掉之前独立的全局CORS配置类,避免冲突

3. 配置Swagger UI支持跨域凭证

Swagger UI发起请求时需要携带凭证,否则Keycloak会拒绝:

@Configuration
public class SwaggerConfig {
    @Bean
    public OpenAPI customOpenAPI() {
        return new OpenAPI()
            .info(new Info().title("Gateway API").version("v1"));
    }

    @Bean
    public SwaggerUiConfigParameters swaggerUiConfigParameters() {
        SwaggerUiConfigParameters params = new SwaggerUiConfigParameters();
        params.setTryItOutEnabled(true);
        // 开启携带凭证,解决跨域时的身份校验问题
        params.setWithCredentials(true);
        return params;
    }
}

4. 排查Docker Keycloak的网络问题

  • 本地开发建议给Keycloak容器用host网络模式,避免端口映射导致的源地址混淆:
    docker run -d --network host -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:latest start-dev
    
  • 如果用端口映射,确保Keycloak的KEYCLOAK_FRONTEND_URL设置正确:
    docker run -d -p 8888:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -e KEYCLOAK_FRONTEND_URL=http://localhost:8888 quay.io/keycloak/keycloak:latest start-dev
    

5. 调试验证

  • 重启Gateway和Keycloak
  • 先访问http://localhost:8080/v3/api-docs,查看响应头是否包含Access-Control-Allow-Origin: http://localhost:8080
  • 打开浏览器开发者工具的Network标签,查看Swagger UI发起的请求,确认没有CORS报错,且授权请求返回200

内容的提问来源于stack exchange,提问作者çagla boynueğri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 08:57:18