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
相关产品推荐
相关产品推荐

