如何自定义Spring Boot AccessTokenProvider?

时间:2016-03-22 15:40:47

标签: java oauth-2.0 spring-boot azure-active-directory

我想增强OAuth2提供程序的令牌请求。我需要在POST请求中添加一个额外的参数。我不明白在哪里挂钩Spring Boot框架来完成这个。

Spring Boot框架提供了一个用于自定义OAuth2RestTemplate的钩子,如“Customizing the User Info RestTemplate”中所述。我已经实现了以下定制器,它被实例化并按预期调用。不幸的是,在提出令牌请求时似乎没有调用我的提供程序。

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

问题:

如何设置自定义AccessTokeProvder,甚至更好,获取对默认值的引用并使用拦截器或增强器挂钩请求?

代码示例

在下面的分支中,请参阅/ simple模块。将您的AAD租户信息添加到/simple/src/main/resources/application.yml文件中:

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

备注:

  • This commit框架似乎使这成为可能,但如何利用此功能?

  • This question似乎有关系。不知怎的,这家伙增加了一个自定义提供商。但在哪里?

2 个答案:

答案 0 :(得分:1)

作为一种解决方法,我将资源添加到配置文件中,并添加了以下两个类来捕获OAuth2RestTemplate并添加请求增强器。

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

答案 1 :(得分:1)

我遇到了同样的问题,并使用了这种解决方法,但由于这个原因,我坚持使用弹簧启动1.3.8

所以我开始深入挖掘,然后我终于找到了一种更简单的方法。只需在userAuthorizationUri之后添加资源参数。

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