3

I move from Spring Boot 1.5.20 to Spring Boot 2.1.4. I rewrite my application that was using Zuul and Spring security oauth to Spring cloud gateway and spring-security-oauth2-client.

I try to create spring cloud gateway filter to add JWT bearer token. I'm having issue to write the filter.

Here's the workflow

I've tried to use @RegisteredOAuth2AuthorizedClient but it didn't work with Spring cloud gateway filter. After, I tried oAuth2AuthorizedClientService and to UAA loadAuthorizedClient but there was no access token.

For the code, here's my github-repo!

I expect the Spring cloud gateway filter to add the header Authorization with the JWT Token.

ltlamontagne
  • 31
  • 2
  • 3

2 Answers2

1

You can create this filter:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.security.oauth2.client.AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;

import lombok.Getter;
import lombok.Setter;


public class Oauth2ClientGatewayFilter2 extends AbstractGatewayFilterFactory<Oauth2ClientGatewayFilter2.Config> {


    

    
    @Autowired
    private ReactiveClientRegistrationRepository clientRegistrations;
    
    @Autowired
    private ReactiveOAuth2AuthorizedClientService clientService;

    public Oauth2ClientGatewayFilter2() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {

        return (exchange, chain) -> {
            
            OAuth2AuthorizeRequest oAuth2AuthorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId("myClient")
                    .principal("myPrincipal").build();

            
        
            
            ReactiveOAuth2AuthorizedClientManager manager =  new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(clientRegistrations,clientService);

            return manager.authorize(oAuth2AuthorizeRequest)
                    .map(client -> client.getAccessToken().getTokenValue())
                    .map(bearerToken -> {
                        ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
                        builder.header(HttpHeaders.AUTHORIZATION, "Bearer " + bearerToken);
                        ServerHttpRequest request = builder.build();
                        return exchange.mutate().request(request).build();
                    }).defaultIfEmpty(exchange).flatMap(chain::filter);

        };


    }

    @Getter
    @Setter
    public static class Config {
        private String clientRegistrationId;
    }


}

and define your OAuth2 configuration in application.yaml:

spring:
  security:
    oauth2:
      client:
        registration:
          myClient:
            client-name: myClient
            client-id: amiga-client
            client-secret: ee073dec-869d-4e8d-8fa9-9f0ec9dfd8ea
            authorization-grant-type: client_credentials         
        provider:
          myClient:
            token-uri: https://myserver.com/auth/oauth/v2/token

You just ask the OAuth2 bearer access token to the ReactiveOAuth2AuthorizedClientManager and set its value in the Authorization header of current request.

Claudio Tasso
  • 417
  • 5
  • 13
  • This solution seems to be working great! What does principal do though? It seems to make no difference to me when leaving it out... – sandrooco Feb 13 '23 at 09:37
-1

This sample shows how to set up Spring Cloud Gateway with Spring Security OAuth2.

OlgaMaciaszek
  • 3,662
  • 1
  • 28
  • 32
  • 1
    I try with TokenRelayGatewayFilterFactory but it didn't work. It is not able to get [exchange.getPrincipal()](https://github.com/spring-cloud/spring-cloud-security/blob/master/spring-cloud-security/src/main/java/org/springframework/cloud/security/oauth2/gateway/TokenRelayGatewayFilterFactory.java#L50) – ltlamontagne May 08 '19 at 17:17