Brett
Brett

Reputation: 8745

How do I customize the Spring Boot AccessTokenProvider?

I want to enhance the token request for my OAuth2 provider. I need to add an additional parameter to the POST request. I don't understand where to hook into the Spring Boot framework to accomplish this.

The Spring Boot framework provides a hook for customizing the OAuth2RestTemplate as described in "Customizing the User Info RestTemplate". I have implemented the following customizer, which gets instantiated and called as expected. Unfortunately, my provider does not seem to get called when the token request is made.

public class AadUserInfoRestTemplateCustomizer implements UserInfoRestTemplateCustomizer {
    @Override
    public void customize(OAuth2RestTemplate oAuth2RestTemplate) {

        oAuth2RestTemplate.setAuthenticator(new AadOauth2RequestAuthenticator());

        // Attempt 1: Use my own token provider, but it never gets called...
        oAuth2RestTemplate.setAccessTokenProvider(new AadAccessTokenProvider());

        // Even better, if only OAuth2RestTemplate provided a getter for AccessTokenProvider, I could add interceptors and or enhancers
        // Can't do this :( AuthorizationCodeAccessTokenProvider provider = oAuth2RestTemplate.getAccessTokenProvider();
    }
}

QUESTION:

How does set a custom AccessTokeProvder, or even better, get a reference to the default one and hook into the request with an interceptor or enhancer?

CODE SAMPLE

In the fork below, please see the /simple module. Add your AAD tenant info into the /simple/src/main/resources/application.yml file:

https://github.com/bmillerbma/tut-spring-boot-oauth2/tree/aad

NOTES:

Upvotes: 3

Views: 4716

Answers (2)

Nergal
Nergal

Reputation: 1015

I came across with the same issue and used this workaround but because of this I stuck with spring boot 1.3.8

So I started to dig deeper and then I finally found an easier method. Just add a resource parameter after the userAuthorizationUri.

security:
  oauth2:
    client:
      ...
      userAuthorizationUri: https://login.microsoftonline.com/<<tenantId>>/oauth2/authorize?resource=https://graph.windows.net
      ...

Upvotes: 1

Brett
Brett

Reputation: 8745

As a workaround, I added the resource to my config file and added the following two classes to capture the OAuth2RestTemplate and add request enhancers.

application.yaml:

aad:
  resource: https://graph.windows.net

security:
  oauth2:
    client:
      clientId: [clientid]
etc.

@Component
public class AzureRequestEnhancerCustomizer {
    @Autowired
    private OAuth2RestTemplate userInfoRestTemplate;

    @Autowired
    private AzureRequestEnhancer azureRequestEnhancer;

    @PostConstruct
    public void testWiring() {
        AuthorizationCodeAccessTokenProvider authorizationCodeAccessTokenProvider = new AuthorizationCodeAccessTokenProvider();
        authorizationCodeAccessTokenProvider.setTokenRequestEnhancer(azureRequestEnhancer);
        userInfoRestTemplate.setAccessTokenProvider(authorizationCodeAccessTokenProvider);
    }
}

@Component
public class AzureRequestEnhancer implements RequestEnhancer {
    @Value("${aad.resource:null}")
    private String aadResource;

    @Override
    public void enhance(AccessTokenRequest request, OAuth2ProtectedResourceDetails resource, MultiValueMap<String, String> form, HttpHeaders headers) {
        if (!StringUtils.isEmpty(resource)) {
            form.set("resource", aadResource);
        }
    }
}

Upvotes: 1

Related Questions