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

Spring Gateway+Spring Auth+资源服务器跨域及认证问题排查

问题分析与解决方案

一、架构基础配置

gateway-url=http://127.0.0.1:9090
authorization-url=http://127.0.0.1:6060
resource-url=http://127.0.0.1:8080
public-spa-url=http://localhost:4200

二、旧方案(表单+Basic Auth)问题修复

1. CORS错误解决

你的CORS问题根源不在Gateway,而是Auth Server的/oauth2/authorize端点未配置跨域允许规则。网关重定向到Auth Server授权端点时,浏览器从http://localhost:9090发起跨域请求,Auth Server没有返回Access-Control-Allow-Origin头导致报错。

在Auth Server的Spring Security配置中添加CORS规则:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().configurationSource(request -> {
            CorsConfiguration config = new CorsConfiguration();
            // 同时允许网关和UI的源,注意localhost和127.0.0.1属于不同同源
            config.setAllowedOrigins(Arrays.asList("http://localhost:9090", "http://localhost:4200"));
            config.setAllowedMethods(Arrays.asList("GET", "POST"));
            config.setAllowedHeaders(Arrays.asList("*"));
            config.setAllowCredentials(true);
            return config;
        }).and()
        // 保留原有OAuth2授权服务器配置
        .oauth2AuthorizationServer(authorize -> authorize
            .authorizationEndpoint(endpoint -> endpoint.baseUri("/oauth2/authorize"))
        );
    }
}

2. 传递Angular登录凭证到Auth Server

网关自行发送客户端凭证,是因为路由未转发Angular请求头中的Authorization信息。需要在Gateway路由配置中添加请求头转发规则:

spring:
  cloud:
    gateway:
      routes:
        - id: auth-server-forward
          uri: ${authorization-url}
          predicates:
            - Path=/oauth2/**
          filters:
            # 转发Angular发送的Authorization头到Auth Server
            - AddRequestHeader=Authorization, {request.headers[Authorization]}
        # 其他资源服务器路由配置...

同时,Auth Server需要开启资源所有者密码模式(匹配你用表单传用户名密码的场景),在客户端配置中添加对应授权类型:

@Bean
public RegisteredClientRepository registeredClientRepository() {
    RegisteredClient apiGatewayClient = RegisteredClient.withId(UUID.randomUUID().toString())
        .clientId("api_gateway_client")
        .clientSecret("{noop}your-client-secret")
        .authorizationGrantType(AuthorizationGrantType.PASSWORD)
        .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
        .redirectUri("http://127.0.0.1:9090/login/oauth2/code/in-house-auth-server")
        .scope("openid")
        .build();
    return new InMemoryRegisteredClientRepository(apiGatewayClient);
}

三、BFF模式问题排查修复

1. BFF服务器类型转换错误

这类错误大多是参数/响应解析不匹配导致:

  • 检查BFF的Controller参数接收:如果用@RequestBody接收Angular请求,确保JSON字段和实体类完全对应,可通过@JsonProperty注解处理驼峰/下划线差异;如果是路径/请求参数,确保类型一致(比如不要把字符串传给Long类型参数)。
  • 检查BFF与Auth Server的交互:避免手动解析OAuth2响应,用Spring官方的OAuth2AuthorizedClient处理认证流程,减少自定义解析的类型错误。

2. Angular端报错排查

  • 先添加错误拦截器打印详细错误信息,定位问题:
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(
      catchError((error: HttpErrorResponse) => {
        console.error('请求错误详情:', error);
        console.error('错误响应体:', error.error);
        return throwError(() => error);
      })
    );
  }
}
  • 若仍存在CORS问题,在BFF中配置允许Angular源:
@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowedOrigins(Collections.singletonList("http://localhost:4200"));
        config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
        config.setAllowedHeaders(Arrays.asList("*"));
        config.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

内容的提问来源于stack exchange,提问作者Sachin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 13:27:22