Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Am trying to use Spring Secruity's OAuth API to obtain an access token from an externally published API.

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'

Am able to obtain an access token from the external service after running this curl command.

When using Spring Security OAuth API:

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

Setup my SpringMVC Controller's method like this:

@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.

Question(s):

  • What am I missing here? Is there some annotation required for this? Is there a property that is not set or is needed?
  • (Please notice that the content-type needs to be "application/x-www-form-urlencoded"...)

  • How can I mimic the working curl command using Spring Security OAuth API?

  • Could it be the default values that I have set in the RequestParameters?

  • If successful, how can I set it up so that access token is always preloaded before any request made?

  • The real reason is, you are using ResourceOwnerPasswordResourceDetails for a "client_credentials" access token request. We cannot interchange ResourceOwnerPasswordResourceDetails and ClientCredentialsResourceDetails.

    In ClientCredentialsResourceDetails you need to set AccessTokenUri, ClientId, ClientSecret and grantType. In ResourceOwnerPasswordResourceDetails, you need to provide Username and Password along with AccessTokenUri, ClientId, ClientSecret and GrantType.

    (Some authserver do accept password token request without username and password.. But I would say it is wrong)

    Refer : Securing an existing API with our own solution

    @Bean
    public RestTemplate oAuthRestTemplate() {
        ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails();
        resourceDetails.setId("1");
        resourceDetails.setClientId(oAuth2ClientId);
        resourceDetails.setClientSecret(oAuth2ClientSecret);
        resourceDetails.setAccessTokenUri(accessTokenUri);
        OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails, oauth2ClientContext);
        return restTemplate;
    

    The correct headers will be set bij the framework, but the username/password will be base64 encodes as Authorization header (basic authentication). This is the OAuth2 spec for a client_credentials grant.

    Check if the api supports the spec:

    curl -X POST \
    'https://api.app.com/v1/oauth/token' \
    -i -u 'client:secret' \
    -H 'Content-Type: application/x-www-form-urlencoded' \
    -d 'grant_type=client_credentials'
    

    If you need to send the username & password as data instead of authorisation header, you can add resourceDetails.setAuthenticationScheme(AuthenticationScheme.form); this should set de username & password as data

    This could be oocured beacuse server doest not recognize the content type you posting to that specific url. In your CURL request try include the 'content-type: application/x-www-form-urlencoded' for custom conrtroller using http headers.

    Also you have not set username and password for resourceDetails. resourceDetails.setUserName("user"); resourceDetails.setUserName("password");

    if those does not work try to extract the request that Encoded with application/x-www-form-urlencoded and pass it as a string via RestTemplate and you can get the token.

    Let me know any if you need additional support.

    Try the code below that is giving token as and string response.

    thanks for the response! How would I set that since this is OAuth2RestTemplate instead of RestTemplate? Also, if you look at the curl, there's no username / password set. – PacificNW_Lover Jul 9, 2017 at 11:09 then option you have remaining is to include the content_type as application/x-www-form-urlencoded – Osanda Wedamulla Jul 9, 2017 at 11:23 problem is what i have used is RestTemplate and you are using oauth2RestTemplate and you cant set any Http headers and in there unless you change it to RestTempalate. If you can fihure out a method to change that i can provide code. – Osanda Wedamulla Jul 9, 2017 at 11:34 The JavaDoc says that OAuth2RestTemplate is a subclass of RestTemplate: docs.spring.io/spring-security/oauth/apidocs/org/… – PacificNW_Lover Jul 9, 2017 at 18:14

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.