How to refresh Token in GoogleCredential - android

I have implement function retrieve credentials from saved token in SharedPreferences.
mCredential = new GoogleCredential.Builder()
.setClientSecrets(CLIENT_ID, CLIENT_SECRET)
.setJsonFactory(mJsonFactory)
.setTransport(mHttpTransport).build();
mCredential.setRefreshToken(accessRefreshTokenSave);
mCredential.setAccessToken(accessTokenSave);
Long expires = mCredential.getExpiresInSeconds();
boolean result = mCredential.refreshToken();
When the token is expired. We should call mCredential.refreshToken() to refresh the token, is it right ?
When i call refreshToken i got exception.
com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
{
"error" : "invalid_grant"
}
What should i need to do to refresh the token ? I found some document in Using OAuth 2.0 say about refresh token. But i don't know how to implement it in Android code? Is there any sample code do this ?

Generally (in my experience, since I haven't found any documentation) 'invalid grant' means there is some problem with your stored refresh token. This includes (I think):-
The user has revoked it
Your testing has caused multiple refresh tokens to be generated. Only 25 may be extant
The scopes associated with the stored token have changed
To recover the situation, delete the stored refresh token and start the process again. The good news, is that apart from the user revocation scenario (1) this is a testing environment issue and doesn't necessarily mean you have a bug.

Have a look on https://developers.google.com/+/mobile/android/sign-in that's the OAUTH for Android, and you can check what is wrong, or maybe use the example code in your Project. To give you more details, you have to post the entire project (linking it to GitHub for example) or post the interested Class ;-)

Related

How to re use access token for future request and how to refresh access token Android Outlook API

In the example OutlookQuickStart for Android works fine in the first request after logon().Now I want to keep connect my app to that user and continue checking for new emails.. How can I re use the access token and build the request to check for new emails? Do I have to save the access token, refresh token ?
How I can refresh the token in Android if it is expired.
According to the documentation for the auth library at https://github.com/AzureAD/azure-activedirectory-library-for-android, the library caches the token and refresh token for you. So you would just use acquireTokenSilentSync to get the token each time you need it. That function would return the current token from the cache if it is still valid, and would refresh it if it is expired.
UPDATE: I've taken a closer look at the sample you're using and the Outlook SDK that it uses. The key thing here is the DependencyResolver object. You pass that object to the OutlookClient constructor. Then anytime you make an API call with that OutlookClient, it just calls the getCredentials override that you supply when you create the DependencyResolver.
So as the sample stands, you should be able to make multiple calls through that OutlookClient without having to change it at all. However, after an hour, when the access token expires, calls will start to fail. The fix for that would be to change the getCredentials override to always call acquireTokenSilentSync. Something like:
#Override
public Credentials getCredentials() {
logger.debug("getCredentials in resolver called");
AuthenticationResult result = mAuthContext.acquireTokenSilentSync(
scopes,
getResources().getString(R.string.AADClientId),
UserIdentifier.getAnyUser());
logger.debug("AcquireTokenSilentSync SUCCESS");
logger.debug("Token expires: ", result.getExpiresOn());
logger.debug("Token: ", result.getAccessToken());
return new OAuthCredentials(result.getAccessToken());
}
Caveat: I'm unable to run this code to validate it due to problems getting the Android emulator running on my dev machine :(.

Unable to get refresh token with google OAuth 2

Situation
I have simple android app where user gets data from Google Fusion Tables with REST api. For this I was using OAuth 2 authorization to get Access Token and Refresh Token. I have web view in my app which will show login screen as well as consent screen. I was planning to get access token from web view and use it for further API calls. I am using retrofit to execute my http calls. I use following query parameters,
"client_id" = CLIENTID
"client_secret" = SECRET
"code" = 4/XXXXXXXXXX //Code got from redirect url
"grant_type" = "authorization_code"
"access_type" = "offline"
"approval_prompt" = "force"
"redirect_uri" = REDIRECT_URL
So far so good. But when I exceute post request with above query parameters, I get following response,
{
"access_token": "ya29.XXXXXXXXXXXXXX",
"token_type": "Bearer",
"expires_in": 3599,
"id_token": "XXXXXXXXXX"
}
Question
Where is refresh token? I need refresh token because I couldn't do API call through app later on with access token and I don't want user to get access token every time.
What I have tried
I have already followed instructions from this post and have tried revoking permission to application from settings. I have also tried using different google accounts in case there was some permission issue, but still no luck. I have also tried removing query parameter "approval_prompt" and "grant_type" but that also didn't help.
I got answer after searching and banging head for 5-6 hours. This answer saved me! Answer to people looking for this in future,
Add "access_type" = "offline" query while requesting for access token rather than exchanging, i.e. in URL which asks for consent.
Instead of specifying grant_type=offline in the authorization request, you need to provide access_type=offline to request a refresh token.

Android getauthutil getToken not returning a JWT

All,
I am writing an android app and i am trying to use Google+ as my account manager.
I have followed excellent article here and i am prompted to sign into google+ and I event get a token back.
The problem is that the token does not appear to be a JWT ( i know this because there are only 2 dotted parts to the name instead of 3 and that when I pass the "token" to the java referenced in the same article I get an exception suggesting that the all is not well with the token :
com.google.api.client.repackaged.com.google.common.base.Preconditions.checkArgument(Preconditions.java:76)
at com.google.api.client.util.Preconditions.checkArgument(Preconditions.java:37)
at com.google.api.client.json.webtoken.JsonWebSignature$Parser.parse(JsonWebSignature.java:473)
at com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.parse(GoogleIdToken.java:57)
at Checker.check(Checker.java:34)
The code looks like this :-
String scope = "oauth2:server:client_id:";
scope += scope_; // my client id in the web section
scope += ":api_scope:";
String googleauth;
googleauth ="https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/plus.login";
scope+=googleauth;
try
{
String token = GoogleAuthUtil.getToken(act_, s_account, scope);
....
The application does ask for verification and I permit it (and call getToken again as you are supposed to).
But the token appears to be unusable, its bound to be something silly, but as yet I cannot see what.
Regards
Not sure what the problem is, but I've read in several places that you need to put some sort of workaround in place to make it work with the Google authentication. You can have a look at http://www.trajano.net/2014/07/parsing-the-json-web-token-in-java/
Hope this helps

Login to symfony from android device

I have an android app that the user logs in to via facebook. I am trying to access my symfony api without logging in another time. Is it possible to log in to symfony with just the access token that I get from the android app?
Yes, it is possible. You'll need to implement a custom authentication provider and possibly a custom user provider to authenticate a user with token (and possibly retrieve him by token).
Ok so just a wrapup of what I managed to do.
I tried to modify fosFacebookBundle to accept access_tokens but in the end of the day I had to just do everything from scratch following the links I got from Zalas. I got the user from the accesstoken via the FacebookProvider class in fosFacebookBundle.
I had to inject Facebook, and FacebookProvider into my FacebookTokenListener. I am not even shure that this is secure. Somebody might be able to login with a access token from another site(I havn't tested it yet). The accesstoken is also in plaintext in the header. All in all not a very nice solution.
$this->facebook->setAccessToken($request->headers->get("access_token"));
$fbUid = $this->facebook->getUser();
if(!$fbUid){
throw new AccessDeniedHttpException("invalid access token");
}
$user = $this->facebookProvider->findUserByFbId($fbUid);
$token = new FacebookTokenToken($user);
Thanks for the links!

Facebook auth token exchange

Is it possible to authenticate the user on server side using auth token retrieved by Android applicaton from Facebook?
In other words Android application uses SSO and obtain auth token. Then sends this token to backend application deployed on Google App Engine. Then backend application verifies the user against Facebook using the token.
I guess it's not feasible because retrieved token can be used only by Android application, but who knows? Maybe it may be reused somehow?
The Token you get from Android API can be sent to your server, who can check the validity of the token by querying the graph ( using /me?auth_token=.... for example).
The problem is that the same token can be used by any third party - it's not client specific - and so if you base server identification based on that, you have a problem (since a third app could use its user token and get authenticated by you). I am trying to find a way to solve this issue, but I don't have good ideas yet...
Facebook actually has an Android SDK that lets you do this. Information can be found here.
Yes you can. A valid access token is a valid access token. The Graph API does from where the token came, but only that the token has the appropriate permissions to access that portion of the graph api. Keep in mind, though, that the token is only valid for 24 hours from the time of its issuance. (is that really a word?) From the time it is issued?
When using facebook android sdk with SingleSignOn (SSO), the access token format actually changed.
Instead of getting traditional auth token which contains userid & session key as a part of authToken
now we get a different format of authToken
As Facebook Devs are still in process to support there rest apis with newly formated access token
meanwhile we can disable the SSO on android facebook sdk by changing DEFAULT_AUTH_ACTIVITY_CODE to -1 from 32665 (in Facebook.java)
This will invoke Traditional dialouge for granting acess token and in return you'll get access token which will contain session key in it.
Those who are looking for generating secure session key you need to add your own method in Facebook.java like
public String getSessionSecret(String accessToken) throws MalformedURLException, IOException
{
Bundle b = new Bundle();
b.putString("method", "auth.promoteSession");
b.putString("access_token", accessToken);
b.putString("session_key_only", "true");
String response = request(b);
return response;
}

Categories

Resources