Paul Steckler
Paul Steckler

Reputation: 627

Missing parameter access_token on OAuth2 request

I'm using the Apache Amber libraries to try to retrieve an OAuth2 access token from a Web site under my control. My client code is running under Android.

My code is patterned on the example at:

https://cwiki.apache.org/confluence/display/AMBER/OAuth+2.0+Client+Quickstart

In the first step, I'm able to retrieve a "code" by submitting a GET request using a WebView browser:

OAuthClientRequest request = OAuthClientRequest
 .authorizationLocation(AUTHORIZE_URL)
 .setClientId(CLIENT_ID)
 .setRedirectURI(REDIR_URL)
 .setResponseType(CODE_RESPONSE)
 .buildQueryMessage();

 webview.loadUrl(request.getLocationUri());

I use a WebViewClient callback to capture the redirect URL with the "code" parameter. So far, so good.

Using that code, I try to retrieve my access token:

OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());

OAuthClientRequest request = OAuthClientRequest
  .tokenLocation(ACCESS_TOKEN_URL)
  .setGrantType(GrantType.AUTHORIZATION_CODE)
  .setClientId(CLIENT_ID)
  .setClientSecret(CLIENT_SECRET)
  .setRedirectURI(REDIR_URL)
  .setCode(code)
  .buildBodyMessage();

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

Each time I run my code, I get an OAuthProblemException, where the message is that I have an invalid request due to a missing parameter, access_token.

Another StackOverflow post mentions this exception from a similar OAuth2 request, which in that case was caused by having different redirect URIs across OAuth requests. But I've made sure my redirect URIs are the same by using a named constant. Here's the link to that post:

OAuthProblem, missing parameter access_token

Now, I can print out the code returned by the first request, and paste it into a curl command run from my desktop machine:

curl -d "code=...&client_id=...&client_secret=...&grant_type=...&redirect_uri=..." http://my_website.com

and I get a nice JSON response from my site with an access_token.

Why does the call from Java fail, where my hand-rolled command line succeeds?

Upvotes: 3

Views: 5314

Answers (4)

Drunken Daddy
Drunken Daddy

Reputation: 7991

I was having the same problem when trying to get the access token from fitbit OAuth2. buildBodyMessage() and buildQueryMessage() were both giving me missing parameter, access_token.

I believe this is something to do with the apache oauth2 client library. I ended up making simple post requests using spring's RestTemplate and it's working fine.

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("Authorization", "Basic " + "MjI5TkRZOjAwNDBhNDBkMjRmZTA0OTJhNTE5NzU5NmQ1N2ZmZGEw");

MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("client_id", FITBIT_CLIENT_ID);
map.add("grant_type", "authorization_code");
map.add("redirect_uri", Constants.RESTFUL_PATH + "/fitbit/fitbitredirect");
map.add("code", code);

HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.postForEntity(FITBIT_TOKEN_URI, request, String.class);

log.debug("response.body: " + response.getBody());

Upvotes: 0

Wayne
Wayne

Reputation: 1

This is what I encountered and what I did to get it working:

I quickly put together a similar example described in: https://cwiki.apache.org/confluence/display/OLTU/OAuth+2.0+Client+Quickstart and: svn.apache.org/repos/asf/oltu/trunk/oauth-2.0/client/src/test/java/org/apache/oltu/oauth2/client/OAuthClientTest.java

This was my command to execute it:

java -cp .:./org.apache.oltu.oauth2.client-1.0.1-20150221.171248-36.jar OAuthClientTest

I also ended up with the above mentioned error where the access_token was expected. I ended up debugging in intellij and traced an anomaly with the if condition which checks that the string begins with the "{" character.

In doing so, I also added the following jar to my classpath so that I may debug the trace a little deeper. ./java-json.jar (downloaded from http://www.java2s.com/Code/Jar/j/Downloadjavajsonjar.htm)

During the next debug session, the code actually started working. My mate and I eventually found the root cause was due to the JSON jar not being included.

This is the command which works:

java -cp .:./java-json.jar:./org.apache.oltu.oauth2.client-1.0.1-20150221.171248-36.jar OAuthClientTest

Upvotes: 0

moisesbelda
moisesbelda

Reputation: 126

Solved in my case.

Amber/Oltu "Missing parameter access_token" error may mean that GitHubTokenResponse or OAuthJSONAccessTokenResponse are unabled to translate response body for any reason. In my case (with Google+ oAuth2 authentication), the response body, is not parsed properly to the inner parameters map.

For example: GitHubTokenResponse

 parameters = OAuthUtils.decodeForm(body);

Parse a form-urlencoded result body

... and OAuthJSONAccessTokenResponse has the next parse function

 parameters = JSONUtils.parseJSON(body);

This JSONUtils.parseJSON is a custom JSON parser that not allow for me JSON response body from GOOGLE+ and throws an JSONError (console not logged),

Each error throwed parsing this parameters, are not console visible, and then always is throwed doomed "Missing parameter: access_token" or another "missing parameter" error.

If you write your Custom OAuthAccessTokenResponse, you can see response body, and write a parser that works with your response.

Upvotes: 0

Francisco Ferri
Francisco Ferri

Reputation: 189

I had the same problem implementing the client and the server, the problem is about one mistake in the Client Example in the Apache Amber (Oltu) project:

First you have the Auth code request (which work):

OAuthClientRequest request = OAuthClientRequest
    .authorizationLocation(AUTHORIZE_URL)
    .setClientId(CLIENT_ID)
    .setRedirectURI(REDIR_URL)
    .setResponseType(CODE_RESPONSE)
    .**buildQueryMessage**();

And second the request about the Access Token (which don't work):

OAuthClientRequest request = OAuthClientRequest
    .tokenLocation(ACCESS_TOKEN_URL)
    .setGrantType(GrantType.AUTHORIZATION_CODE)
    .setClientId(CLIENT_ID)
    .setClientSecret(CLIENT_SECRET)
    .setRedirectURI(REDIR_URL)
    .setCode(code)
    .**buildBodyMessage**();

The mistake is about the buildBodyMessage() in the second request. Change it by buildQueryMessage().

Upvotes: 3

Related Questions