简体   繁体   中英

Spring WebClient Configuration Okta OAuth2

I'm building an API Gateway which uses Spring Webflux, Spring Cloud Gateway, Spring Cloud Security & Okta for OAuth2.

Here's my RouteLocator, through which I can call my Foo Microservice.

@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();
}

This works perfectly fine.

However, since I need to aggregate the results of different microservices, let's say Foo and Bar, I'm creating a load balanced Spring WebClient bean that I can use to make http calls:

@Bean
@LoadBalanced
public WebClient.Builder webClientBuilder() {
    return WebClient.builder();
}

How can I configure the WebClient to pass the Token on every request the same way as the TokenRelayGatewayFilterFactory does in the RouteLocator?

EDIT:

Here's my updated 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);
}

Now it seems like it is working on the Chrome browser. After logging in on Okta I can access /foo on Foo microservice through Http GET. Although when I try an Http POST on /foo through Postman, (while adding the Authorization header), I'm getting a 302 response that redirects me to an Okta html page.

Funnily enough, using the RouteLocator I don't get any redirection and both GET and POST work through Postman. The redirection seems to be happening only when using WebClient.

Any idea why?

EDIT #2:

My Security config file:

@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);
    }
}

Take a look at ServletOAuth2AuthorizedClientExchangeFilterFunction (or the reactive equivalent) This video covers it in more detail: https://youtu.be/v2J32nd0g24?t=2168

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM