Benj F
Benj F

Reputation: 291

Access tokens using 2 legged Oauth 2.0 and Apache OauthClient

I'm trying get 2 legged Oauth 2 working. I'm trying to mimic this CURL call to get an access token:

curl -u CLIENT_ID:CLIENT_SECRET https://mydomain.com/token -d "grant_type=client_credentials"

I'm trying to do the same thing in Java using Apache Oltu:

<dependency>
    <groupId>org.apache.oltu.oauth2</groupId>
    <artifactId>org.apache.oltu.oauth2.client</artifactId>
    <version>1.0.0</version>
</dependency>

This is the Java code I'm using:

OAuthClientRequest request = OAuthClientRequest
            .tokenLocation("https://mydomain.com/token")
            .setGrantType(GrantType.CLIENT_CREDENTIALS)
            .setClientId(CLIENT_ID)
            .setClientSecret(CLIENT_SECRET)
            .buildBodyMessage();


//create OAuth client that uses custom http client under the hood
OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());

OAuthJSONAccessTokenResponse oAuthResponse = oAuthClient.accessToken(request, OAuthJSONAccessTokenResponse.class);

The CURL command works fine but the Java code gives this error:

OAuthProblemException{error='invalid_request', description='Must include a basic access authentication header.', uri='null', state='null', scope='null', redirectUri='null', responseStatus=0, parameters={}}

I tried using the header message build:

.buildHeaderMessage();

instead but it gives:

OAuthProblemException{error='invalid_request', description='Must specify grant_type field.', uri='null', state='null', scope='null', redirectUri='null', responseStatus=0, parameters={}}

Any suggestions are appreciated. I would expect this to be pretty straightforward.

Upvotes: 1

Views: 6524

Answers (2)

imarchuang
imarchuang

Reputation: 479

Recently, I've trying to find a OAuth2 java library to get "client_credential" type of accesstoken. And below is what I have, and it seems that it does work.

@Test
public void getAccessTokenViaApacheOltuOAuthClient() {
    try{

        OAuthClient client = new OAuthClient(new URLConnectionClient());

        OAuthClientRequest request =
                OAuthClientRequest.tokenLocation(TOKEN_REQUEST_URL)
                        .setGrantType(GrantType.CLIENT_CREDENTIALS)
                        .setClientId(CLIENT_ID)
                        .setClientSecret(CLIENT_SECRET)
                        .setScope(StringUtils.join(TEST_SCOPES, " ")) //if you have scope
                        .buildBodyMessage();

        String token =
                client.accessToken(request, "POST", OAuthJSONAccessTokenResponse.class)
                        .getAccessToken();

        System.out.println(token);
        assertTrue( token != null);

    } catch (Exception e) {
        e.printStackTrace();
    }
}

Upvotes: 0

Benj F
Benj F

Reputation: 291

I have given up on Apache Oltu Oauth and come up with two alternate solutions. The latter being the preferred.

Solution 1: Low level HTTP calls

For my first try I went back to basics and used the HttpClient library.

<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpclient</artifactId>
  <version>4.3.3</version>
</dependency>

I was able to get the Oauth access token using the following code:

HttpPost request = new HttpPost("https://mydomain.com/token");
List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
urlParameters.add(new BasicNameValuePair("grant_type", "client_credentials"));
request.setEntity(new UrlEncodedFormEntity(urlParameters)); 

String auth = CLIENT_ID + ":" + CLIENT_SECRET;
byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(Charset.forName("US-ASCII")));
String authHeader = "Basic " + new String(encodedAuth);
request.setHeader(HttpHeaders.AUTHORIZATION, authHeader);

HttpClient client = HttpClientBuilder.create().build();
HttpResponse response = client.execute(request);
System.out.println("Oauth Access Token" + EntityUtils.toString(response.getEntity()));

Solution 2: Spring Oauth2 RestTemplate

I suspected there must be a better way to do Two Legged Oauth 2.0 and was pleased to find the Spring Oauth2 Framework

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

This yields far simpler code and provides the framework for subsequent REST calls. This code could be cleaned up with the use of Jackson but I've decided to keep it simple.

String CLIENT_SECRET = "xxxx";
String CLIENT_ID = "yyyy";

ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails();
resourceDetails.setClientSecret(CLIENT_SECRET);
resourceDetails.setClientId(CLIENT_ID);
resourceDetails.setAccessTokenUri("https://mydomain.com/token");

OAuth2RestTemplate oAuthRestTemplate = new OAuth2RestTemplate(resourceDetails);

HttpHeaders headers = new HttpHeaders();
headers.setContentType( MediaType.APPLICATION_JSON );

// Sample POST Method
String postJson = "{\"phone\":\"15554443333\", \"ip\":\"67.666.666.666\"}";
HttpEntity<String> reqEntity = new HttpEntity<String>(postJson, headers);
String postUri = "https://mydomain.com/v1.0/phone.json";
String postResult = oAuthRestTemplate.postForObject(postUri, reqEntity, String.class);
System.out.println(postResult);

// Sample GET method
String getUri = "https://mydomain.com/v1.0/phone.json?phone=15554443333";
String result = oAuthRestTemplate.getForObject( getUri, String.class);
System.out.println(result);

Upvotes: 2

Related Questions