我正在构建一个API网关,该网关使用SpringWebflux、SpringCloudGateway、SpringCloudSecurity&Okta表示OAuth2。
这是我的RouteLocator,通过它我可以调用我的Foo微服务。
@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder, TokenRelayGatewayFilterFactory filterFactory) {
return builder.routes()
.route("foo", r ->
r.path("/foo")
.filters(f -> f
.rewritePath("/foo", "/api/v1/foo")
.filter(filterFactory.apply()))
.uri("lb://foo-service")
)
.build();
}
这非常好用。
然而,由于我需要聚合不同微服务的结果,比如Foo和Bar,我正在创建一个负载平衡的SpringWebClientbean,可以用来进行http调用:
@Bean
@LoadBalanced
public WebClient.Builder webClientBuilder() {
return WebClient.builder();
}
我如何配置WebClient以像RouteLocator中的TokenRelayGatewayFilterFactory一样在每个请求上传递令牌?
编辑:
这是我更新的WebClient bean:
@Bean
@LoadBalanced
public WebClient.Builder webClientBuilder(ReactiveClientRegistrationRepository clientRegistrations,
ServerOAuth2AuthorizedClientRepository authorizedClients) {
var oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrations, authorizedClients);
oauth.setDefaultOAuth2AuthorizedClient(true);
oauth.setDefaultClientRegistrationId("okta");
return WebClient
.builder()
.filter(oauth);
}
现在它似乎正在Chrome浏览器上运行。登录Okta后,我可以通过HttpGET访问foo微服务上的/foo。尽管当我通过Postman在/foo上尝试HttpPOST时(在添加Authorization头的同时(,我得到了一个302响应,它将我重定向到一个Oktahtml页面。
有趣的是,使用RouteLocator我没有得到任何重定向,get和POST都通过Postman工作。重定向似乎只有在使用WebClient时才会发生。
知道为什么吗?
编辑#2:
我的安全配置文件:
@Configuration
@EnableWebFluxSecurity
class SecurityConfig {
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
return http
.csrf().disable()
.authorizeExchange().anyExchange().authenticated()
.and()
.oauth2Login()
.and()
.oauth2ResourceServer().jwt()
.and()
.and().build();
}
@Bean
CorsWebFilter corsWebFilter(){
CorsConfiguration corsConfig = new CorsConfiguration();
corsConfig.setAllowedOrigins(List.of("*"));
corsConfig.setMaxAge(3600L);
corsConfig.addAllowedMethod("*");
corsConfig.addAllowedHeader("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfig);
return new CorsWebFilter(source);
}
}
查看ServletOAuth2AuthorizedClientExchangeFilterFunction(或等效的反应式(本视频更详细地介绍了它:https://youtu.be/v2J32nd0g24?t=2168