Mr. Kadiev
Mr. Kadiev

Reputation: 310

Can not set up proxy setting for Spring Cloud API Gateway based project

I'm using Spring Cloud API Gateway, the app has yaml based configuration and it works well since all routes are internal links, means there is no need for any proxy.

But, there a dependency on Spring Security which is used to validate JWT token and the URL of issuer is the resource that can be reached only via proxy.

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          jwk-set-uri: https://some-site.com/itmp/v1/.well-known/jwks.json
          issuer-uri: https://some-site.com/itmp/v1/

And here is the problem: I can not force WebClient using the http.proxyHost parameter. I tried many techniques that I found all around the Internet like setting them implicitly in app properties file, or hard coded in application itself. But nothing worked out for me. Maybe I'm missing something, maybe Spring Cloud has some special tweaks for that behavior?

FYI Project is based on Spring Boot 2.6.6 (reactor-netty 1.0.17 which is normally supports proxyWithSystemProperties )

Upvotes: 1

Views: 1155

Answers (1)

Thomas Kåsene
Thomas Kåsene

Reputation: 5449

I recently had this exact problem myself. After a lot of back and forth I ended up creating my own ReactiveJwtDecoder bean and setting the HttpClient/WebClient it uses internally (using NimbusReactiveJwtDecoder.webClient(WebClient)). Something along the lines of:

@Bean
ReactiveJwtDecoder jwtDecoder(@Value("${ISSUER_URI}") String issuerUri,
                              @Value("${JWKS_URI}") String jwksUri) {

    HttpClient httpClient = HttpClient.create().proxyWithSystemProperties();
    WebClient webClient = WebClient.builder()
            .clientConnector(new ReactorClientHttpConnector(httpClient))
            .build();

    var jwtDecoder = NimbusReactiveJwtDecoder
            .withJwkSetUri(jwksUri)
            .webClient(webClient)
            .build();

    // import org.springframework.security.oauth2.jwt.JwtValidators;
    jwtDecoder.setJwtValidator(JwtValidators.createDefaultWithIssuer(issuerUri));

    return jwtDecoder;
}

You can probably inject the OAuth2ResourceServerProperties-bean instead of those two @Value-annotated Strings to get the URLs.

Also, be aware that if you application already does more customized JWT claim validation than merely checking iss, exp and nbf, you must remember to inject the existing JwtValidator and use that instead of the JwtValidators.createDefaultWithIssuer(String) one.

Upvotes: 1

Related Questions