How to set HTTP Header for OAuth2RestTemplate

二次信任 提交于 2019-12-07 08:25:25

问题


Am trying to use Spring Secruity's OAuth API to obtain an access token from an externally published API within a Spring MVC 4 based Web Services (not Spring Boot).

This curl command works (and its contents are all that I need to obtain an access token):

curl -X POST \
https://api.app.com/v1/oauth/token \
  -H 'content-type: application/x-www-form-urlencoded' \
  -d'grant_type=client_credentials&client_id=bcfrtew123&client_secret=Y67493012'

Spring Security OAuth API:

<dependency>
   <groupId>org.springframework.security.oauth</groupId>
     <artifactId>spring-security-oauth2</artifactId>
     <version>2.1.1.RELEASE</version>
</dependency>

My code to obtain access token:

@RequestMapping(value = "/getAccessToken", method = RequestMethod.POST, consumes="application/x-www-form-urlencoded")
public OAuth2AccessToken getAccessToken(@RequestParam(value="client_id", required=true) String clientId, @RequestParam(value="client_secret", required=true) String clientSecret) throws Exception {
    String tokenUri = "https://api.app.com/v1/oauth/token";

    ResourceOwnerPasswordResourceDetails resourceDetails = new ResourceOwnerPasswordResourceDetails();

    resourceDetails.setAccessTokenUri(tokenUri);
    resourceDetails.setClientId(clientId);
    resourceDetails.setClientSecret(clientSecret);
    resourceDetails.setGrantType("client_credentials");
    resourceDetails.setScope(Arrays.asList("read", "write"));

    DefaultOAuth2ClientContext clientContext = new DefaultOAuth2ClientContext();

    oauth2RestTemplate = new OAuth2RestTemplate(resourceDetails, clientContext);

    OAuth2AccessToken token = oauth2RestTemplate.getAccessToken();
    return token;
}

When I invoke the getAccessToken call from my local tomcat instance:

access_denied 
error_description=Unable to obtain a new access token for resource 'null'. 
The provider manager is not configured to support it.

Am suspecting the reason is that my Http Header's Content-Type is not set for

application/x-www-form-urlencoded

How do I do set that for:

import org.springframework.security.oauth2.client.OAuth2RestTemplate;

If you notice, I am trying to set in inside the @RequestMapping and don't think that its working:

@RequestMapping(consumes="application/x-www-form-urlencoded") 

回答1:


The http headers for accessing the token in Oauth2Restemplate in case of Client credentials are set in below method of ClientCredentialsAccessTokenProvider (since grant type is client credentials)

public OAuth2AccessToken obtainAccessToken(OAuth2ProtectedResourceDetails details, AccessTokenRequest request)
        throws UserRedirectRequiredException, AccessDeniedException, 
OAuth2AccessDeniedException {

ClientCredentialsResourceDetails resource = (ClientCredentialsResourceDetails) details;
return retrieveToken(request, resource, getParametersForTokenRequest(resource), new HttpHeaders());

}

We can set the http headers by having new custom Access token provider for client credentials and modifying the method as follows:

public OAuth2AccessToken obtainAccessToken(OAuth2ProtectedResourceDetails details, AccessTokenRequest request)
        throws UserRedirectRequiredException, AccessDeniedException, OAuth2AccessDeniedException {

ClientCredentialsResourceDetails resource = (ClientCredentialsResourceDetails) details;

    HttpHeaders headers1 = new HttpHeaders();

    headers1.add("Content-Type", "application/x-www-form-urlencoded");

    return retrieveToken(request, resource, getParametersForTokenRequest(resource), headers1);

}

You can keep the class same as ClientCredentialsAccessTokenProvider and add just the header lines.

Last step will be to set this new class as access token in configuration of Oauth2RestTemplate.

oauth2RestTemplate.setAccessTokenProvider(new ClientCredentialsCustomAccessTokenProvider());

This worked for me!




回答2:


Here's another variation on the answer just to override the default Accept Header interceptor using a Lambda expression:

@Bean
protected RestTemplate restTemplate() {
    return new RestTemplate() {

        @Override
        public <T> RequestCallback acceptHeaderRequestCallback(Class<T> responseType) {
            return request -> {
                request.getHeaders().setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
            };
        }

    };
}



回答3:


If you are using Spring boot mention the authentication scheme as form, it will solve the issue.

security:
  oauth2:
    client:
      clientAuthenticationScheme: form


来源:https://stackoverflow.com/questions/44999532/how-to-set-http-header-for-oauth2resttemplate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!