In an OAuth1 process, I save my token and my secret and recreate my access token like the following:
accessToken = new Token(token, secret);
In an OAuth2 process, I only get a code. If I save this code and try to recreate the access token like following, the app crashes:
Verifier v = new Verifier(code);
accessToken = service.getAccessToken(null, v);
The response:
org.scribe.exceptions.OAuthException: Cannot extract an acces token. Response was: {"code": 400, "error_type": "OAuthException", "error_message": "No matching code found."}
How do I recreate an access token in an OAuth2 process?
I think the problem here is not with your Java code to extract the token (the bit that you're showing at least) - that looks fine from what I can tell.
The error message is a response back from the service you're trying to authorize with (e.g. twitter, or whatever it is in your case) saying that
code
is not known. That could happen if too much time has passed since you got that authorization code from the service, or simply that the authorization code you have is wrong for some reason.
In order to provide proper answer, I'd need to see a bit more code... how precisely are you getting the value of
code
that is going into the constructor of
Verifier
? Please can you provide more of the code you're using for that?
[Sorry, I would have added this as a comment, but don't have enough reputation.]
Related
I am trying to make a Java class which would call upon Google's API to recreate an access token to a user's account with new permissions/larger scope. This class is to be instantiated by a Java servlet I had created. I want a function within that class to return a new access token. For this class to do that, I am using the Scribe library.
In Scribe's quick guide, there are two steps which concern me and have me stumped:
Step Three: Making the user validate your request token
Let’s help your users authorize your app to do the OAuth calls. For
this you need to redirect them to the following URL:
String authUrl = service.getAuthorizationUrl(requestToken);
After this either the user will get a verifier code (if this is an OOB
request) or you’ll receive a redirect from Twitter with the verifier
and the requestToken on it (if you provided a callbackUrl)
Step Four: Get the access Token
Now that you have (somehow) the verifier, you need to exchange your
requestToken and verifier for an accessToken which is the one used to
sign requests.
Verifier v = new Verifier("verifier you got from the user");
Token accessToken = service.getAccessToken(requestToken, v); // the requestToken you had from step 2
It does not seem to specify how to get that verifier from the user. How am I supposed to do that? How do I redirect my user to the authURL, and how do I get it to send its verifier back to this class of mine, which initiated the request to begin with?
If this is unclear, let me structure the question differently, taking Scribe out of the equation: To get an authorization code from Google (which would be used to then get a refresh token and access token), I would execute the following URL connection from within the servlet (yes, I've tried to answer this problem without the Scribe library, and still can't figure it out):
URL authURL = new URL("https://accounts.google.com/o/oauth2/auth");
HttpsURLConnection authCon = (HttpsURLConnection) authURL.openConnection();
authCon.setRequestMethod("GET");
authCon.setDoOutput(false);
authCon.setConnectTimeout(100000);
authCon.setRequestProperty("response_type", "code");
authCon.setRequestProperty("client_id", CLIENT_ID);
authCon.setRequestProperty("redirect_uri",
"http://**************.com/parseAuth/");
authCon.setRequestProperty("scope", convertToCommaDelimited(scopes));
authCon.setRequestProperty("state", csrfSec);
authCon.setRequestProperty("access_type", "offline");
authCon.setRequestProperty("approval_prompt", "auto");
authCon.setRequestProperty("include_granted_scopes", "true");
What has me stuck is what I should be putting for the redirect URI. After getting the user's approval for the new scope, this authorization URL would return an authorization code to the redirect URI, and seemingly nothing to whatever called it. (Am I correct in this?) So if I have another servlet as the redirect URI to parse/extract the authorization code from the response, how in the world do I get that authorization code back to my first, initial servlet? It seems to me that there is no way to have it give back the value to the servlet, in the same position of the code from which the URL was called. It looks like the function has to end there, and all new action must take place within that new servlet. But if that is the case, and I send that auth code to Google's API which would send back a refresh token and access token to ANOTHER servlet I would make to be its redirect URI, how do I possibly get that information back to what it is which called the initial servlet to begin with? That seems to be the same problem at its core, with the problem I am having with Scribe.
I've been stuck on this for many hours, and can't seem to figure out what it is I am supposed to do. I feel like I am missing some key concept, element, or step. I need this clarified. If it is at all relevant, my servlet is hosted on a Jboss application server on OpenShift.
I have an application in whick an user can login with google. Than the user during his experience into the application can choose to integrate also the GoogleCalendar service. In order to achieve this my actual system works like the follow:
-when the user log in with google the system store his access and refresh token and calls Google to retrive basic profile information. In order to do that I create a GoogleCalendar object using the following call:
GoogleTokenResponse response = flow.newTokenRequest(code).setRedirectUri(GOOGLE_CALLBACK_URI).execute();
GoogleCredential credential= new GoogleCredential.Builder().setJsonFactory(Constants.JSON_FACTORY)
.setTransport(Constants.HTTP_TRANSPORT).setClientSecrets(Constants.GOOGLE_CLIENT_ID, Constants.GOOGLE_CLIENT_SECRET).build();
credential.setAccessToken(response.getAccessToken());
credential.setRefreshToken(response.getRefreshToken());
-When the user choose to integrate the calendar service another Oauth iteration starts and the with a new code. I ask the GoogleCredential like before and access the service.
-When the systems need to perform some operations accessing Google Calendar I create a GoogleCredential object with the following call:
GoogleCredential c= new GoogleCredential.Builder().setJsonFactory(Constants.JSON_FACTORY)
.setTransport(Constants.HTTP_TRANSPORT).setClientSecrets(Constants.GOOGLE_CLIENT_ID, Constants.GOOGLE_CLIENT_SECRET).build()
.setAccessToken(user.getAccessToken()).setRefreshToken(user.getRefreshToken());
Ans then ask for the service. But in this last case I get an error reporting 403 code and "Insufficient Permission" message.
I have checked that the stored access and refresh token I set into the GoogleCredential are the same I receive the first time getting the GoogleCredential with the "code". I also search a lot online but no solution would work. I'm really blocked into this error. Thank you in advance for the help and sorry if I miss specifing something or if I make some mistake in asking the question.
If I understand the problem you're describing correctly, incremental authorization may be what you're looking for: https://developers.google.com/accounts/docs/OAuth2WebServer#incrementalAuth
Specifically, add include_granted_scopes=true to your authorization URLs which should cause the resulting tokens to include the sum of all so-far-granted authorizations.
I wonder if someone can help me understand the difference between Access Tokens, App Access Tokens and when to use each.
My problem if that when I use the restFB libraries to obtain the access token:
AccessToken accessTokenT =
new DefaultFacebookClient().obtainAppAccessToken(appID, appSecret);
As I would expect it returns the App Access token. However, when i use that token to instantiate the FacebookClient object:
FacebookClient facebookClient = new DefaultFacebookClient(accessToken);
It fails with the following message:
Exception in thread "main" com.restfb.exception.FacebookOAuthException: Received Facebook error response of type OAuthException: (#200) The user hasn't authorized the application to perform this action (code 200, subcode null)
If I go to the graph explorer and manually get an access token, then use that in my code, everything works fine.
I'm sure there's something subtle I'm missing and any help would be greatly appreciated.
Many thanks
Primarily there are 3 types of access tokens-
User access token
Page access token
App access token
The documentation by facebook: Access Tokens, explains a lot about them. You can have a look.
You should initialize the facebookClient with the user access token. The user access token is obtained when a user login/authorizes the app. This token is used to query about the user(for what he has given permissions to the application). The App access token has very limited powers like: posting on behalf of the user once he has given app the authorization, or send the requests etc.
FB is sending me a non-URL safe code. While implementing the oauth authentication, FB is sending me a code parameter that is non-url safe.
When i authorize the app i am getting the code parameter with the below value which is not url safe.
AQBQnGZgFNv5EcIB9hZI20GcUgBWru7TE-p_G5NB2HQLX87fyc463aM0BIAiBg_PwRiIuyo0KS1vrDLOLB_SQ0goY31RrNYtZ23lOeaOkGzztarMYH8bJpSYjFOgiXbPhcP6h9YCsizekmcbLpPX_3F7qhsZOLM37UGI7QysvyYOvptpgJ-fm5t-eSViIU_CQH8jTPcQu3BylUVIXS0cEt5T#___=_
When FB is redirecting the control to the my url which is a java web application, i tried to get the code parameter using the code "request.getParameter(CODE)" But i am getting only
AQBQnGZgFNv5EcIB9hZI20GcUgBWru7TE-p_G5NB2HQLX87fyc463aM0BIAiBg_PwRiIuyo0KS1vrDLOLB_SQ0goY31RrNYtZ23lOeaOkGzztarMYH8bJpSYjFOgiXbPhcP6h9YCsizekmcbLpPX_3F7qhsZOLM37UGI7QysvyYOvptpgJ-fm5t-eSViIU_CQH8jTPcQu3BylUVIXS0cEt5T
without #___=_
so i am not able to continue further. But i manually add it to the parameter to fetch the access token it is working fine.
Why is this happening? Please help me.
i think this is signed_request code.
You doesn't need the #_=_ trail to get further, it's not a part of signed_request or code for OAuth2. If you can proceed to further steps it's something other that this.
Once you get code passed to redirect_uri URL you can continue with authentication:
In order to authenticate your app, you must pass the authorization code and your app secret to the Graph API token endpoint - along with the exact same redirect_uri used above - at https://graph.facebook.com/oauth/access_token.
https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&
client_secret=YOUR_APP_SECRET&code=THE_CODE_FROM_ABOVE
I am developing a Java Application where I am implementing 3-legged OAuth using google gdata in Java. This application is registered on Google App Engine. At the first stage, I am getting the unauthorized request-token successfully. I am storing that token in session and create a link using createUserAuthorizationUrl(oauthParameters). Then on clicking the link, it redirect me to "Grant Access Page".
Now, even though I grant access, it doesn't show me this page. But, it redirects me to my callback url. However, this seems proper. But, it also doesn't add the entry under My Account. Here, I am storing the oauth_token in session.
When getting redirected, the url of that page contains oauth_token & oauth_verifier, both ! Now, on this callback url, I have a submit button & set action of for to an accessTokenServlet.java. The code of this servlet is as follow :
Now I am sending request to fetch Access Token. My code is :
GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
oauthParameters.setOAuthConsumerKey(CONSUMER_KEY);
oauthParameters.setOAuthConsumerSecret(CONSUMER_SECRET);
oauthParameters.setOAuthType(OAuthParameters.OAuthType.THREE_LEGGED_OAUTH);
GoogleOAuthHelper oauthHelper = new GoogleOAuthHelper(new OAuthHmacSha1Signer());
oauthParameters.setOAuthToken(request.getSession().getAttribute("oauth_token").toString());
oauthParameters.setOAuthTokenSecret(request.getSession().getAttribute("oauth_token_secret").toString());
try {
String accessToken = oauthHelper.getAccessToken(oauthParameters);
out.println("Access Token : " + accessToken);
} catch (OAuthException e) {
//System.out.print("Response Status : " + response.getStatus());
out.println("Exception : ");
e.printStackTrace();
return;
}
While clicking on submit button, it prints "Access Token : " & nothing ! No token returns !
I am getting wrong at the stage of authorizing the request token itself. But, I am not getting, what problem got generated ?
The page with the verifier you linked to should only happen if you pass in an oauth_callback of oob — this indicates that you will be moving the verifier out-of-band. I strongly recommend against using oob for anything but debugging. Instead, you should be setting a callback URL and getting the verifier out of the query string.
In the code above, I don't see anything that sets the verifier in the OAuth parameters, so that's likely your problem. You're also not doing much in the way of error handling, and that's a really important piece of the OAuth flow — for example, once you've got it working, try canceling the OAuth process and see how your application handles it.
You will only see the entry in your issued tokens list after you've fully completed the process and obtained an upgraded access token.