简体   繁体   English

将OAuth2RestTemplate公开为AsyncRestTemplate

[英]Exposing OAuth2RestTemplate as AsyncRestTemplate

I have a working OAuth2RestTemplate client (I'm using spring-security-oauth2 2.0.7.RELEASE). 我有一个工作的OAuth2RestTemplate客户端(我使用的是spring-security-oauth2 2.0.7.RELEASE)。 Now I'd like to expose/wrap it as AsyncRestTemplate to take advantage of asynchronous semantic of ListenableFuture. 现在我想将它暴露/包装为AsyncRestTemplate以利用ListenableFuture的异步语义。 Unfortunately the following straightforward approach doesn't work: 不幸的是,以下简单的方法不起作用:

// instantiate and configure OAuth2RestTemplate - works
OAuth2RestTemplate oAuth2RestTemplate = new OAuth2RestTemplate(...);

// wrap sync restTemplate with AsyncRestTemplate - doesn't work 
AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate(
    new HttpComponentsAsyncClientHttpRequestFactory(), oAuth2RestTemplate);

How can I get OAuth2 Rest client for my HTTP service as AsyncRestTemplate? 如何将我的HTTP服务的OAuth2 Rest客户端作为AsyncRestTemplate获取?

Ok, I was able to make AsyncRestTemplate work by manually setting "Authorization" header with accessToken from OAuth2RestTemplate; 好的,我能够通过从OAuth2RestTemplate手动设置带有accessToken的“Authorization”标题来使AsyncRestTemplate工作; here's Spring java configuration for that: 这是Spring的配置:

@Bean
public OAuth2RestTemplate restTemplate() {
    ClientCredentialsResourceDetails details = new ClientCredentialsResourceDetails();
    // configure oauth details

    OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(details);
    restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());

    return restTemplate;
}

@Bean
public AsyncRestTemplate asyncRestTemplate(final OAuth2RestTemplate oAuth2RestTemplate) {
    HttpComponentsAsyncClientHttpRequestFactory asyncRequestFactory = new HttpComponentsAsyncClientHttpRequestFactory() {
        @Override
        public AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod httpMethod) throws IOException {
            AsyncClientHttpRequest asyncRequest = super.createAsyncRequest(uri, httpMethod);

            OAuth2AccessToken accessToken = oAuth2RestTemplate.getAccessToken();
            asyncRequest.getHeaders().set("Authorization", String.format("%s %s", accessToken.getTokenType(), accessToken.getValue()));

            return asyncRequest;
        }
    };
    return new AsyncRestTemplate(asyncRequestFactory, oAuth2RestTemplate);
}

I wish there would be easier way to expose configured OAuth2RestTemplate as AsyncRestTemplate in Spring. 我希望有更简单的方法在Spring中将配置的OAuth2RestTemplate公开为AsyncRestTemplate。

The above works, but I've found a much neater way of doing it. 上面的工作,但我发现了一个更简洁的方法。 Register an implementation AsyncClientHttpRequestInterceptor 注册实现AsyncClientHttpRequestInterceptor

Example code: 示例代码:

private class Oauth2RequestInterceptor implements AsyncClientHttpRequestInterceptor
{
    private final OAuth2RestTemplate oAuth2RestTemplate;

    public Oauth2RequestInterceptor( OAuth2RestTemplate oAuth2RestTemplate )
    {
        this.oAuth2RestTemplate = oAuth2RestTemplate;
    }

    public ListenableFuture<ClientHttpResponse> intercept( HttpRequest request, byte[] body,
        AsyncClientHttpRequestExecution execution ) throws IOException
    {
        OAuth2AccessToken accessToken = oAuth2RestTemplate.getAccessToken();
        request.getHeaders()
            .set( "Authorization", String.format( "%s %s", accessToken.getTokenType(), accessToken.getValue() ) );
        return execution.executeAsync( request, body );
    }
}

Then register it with your AsyncRestTemplate : 然后使用AsyncRestTemplate注册它:

@Bean
public AsyncRestTemplate asyncRestTemplate( AsyncClientHttpRequestFactory factory, OAuth2RestTemplate restTemplate )
{
    AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate( factory, restTemplate );
    asyncRestTemplate.setInterceptors( Collections.singletonList( new Oauth2RequestInterceptor( restTemplate ) ) );
    return asyncRestTemplate;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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