How to get OAuth 2 refresh token using access token - android

I am developing an app in which i am using OAuth 2.0 to upload data in user Google label. I am able to connect to the users mail and after some time access token expires. How to get new access token using Token refresher?
I am using javamail sample code to authenticate and get access token. I am searching it from many days but did not found any running code. I am new to android, so please provide some code or complete sample code.

I got the answer now i want to share to all of you because many questions are unanswered.
to get a new token first you have to invalidate the token using below code
accountManager.invalidateAuthToken("com.google", token);
after invalidating the token you require to get a new Token, below code provides a new Token
String newToken = AccountManager.get(this).getAuthToken(new Account(account, "com.google"),
AUTH_TOKEN_TYPE, true, null, null).getResult().getString(AccountManager.KEY_AUTHTOKEN);
now you can use your new token to authenticate and login.

Related

Android login via Google Sign-In with a Spring Boot backend

As the title says, I'm trying to use the Google Sign-In API with a Spring Boot backend server, as described here.
Just to describe the context, the Spring backend is basically a resource+authentication server, that is currently providing Oauth2 authentication to a second spring boot application containing the frontend website, via Google SSO or simple form login (similar to what's described here).
My original idea was to mimic the #EnableOauth2Sso annotation by simply providing an access token to the android app and attach it to every request as "Bearer ".
Using the user credentials for this was pretty straightforward: I simply make a request to the server at "/oauth/token", using those credentials inserted by the user as authentication and I correctly receive the access token.
Now, I have absolutely no idea on how to build a similar procedure with the Google API in Android. The tutorial page I linked before describes how to get a token ID and how the server should validate it, but after that I don't know what to do.
So far I've managed to add a filter to the security chain that simply checks the token like this:
private Authentication attemptOpenIDAuthentication(#NonNull String tokenString){
String clientId = authServices.getClientId();
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, factory)
.setAudience(Arrays.asList(clientId, androidClient))
.build();
try {
GoogleIdToken token = verifier.verify(tokenString);
if (token != null) {
return authServices.loadAuthentication(token.getPayload());
} else {
throw new InvalidTokenException("ID token is null");
}
} catch (GeneralSecurityException | IOException e) {
throw new BadCredentialsException("Could not validate ID token");
}
}
This manages indeed to create an Authentication object, but how can I generate an access token after the authentication filtering?
To recap, so far I've got:
The Android app successfully retrieves the Google token ID and sends it to the server
The server sucessfully intercepts the request and validates the token
I'm basically missing the third point where I return a proper access token to the Android client.
Here you are a simple scheme to better understand the situation:
Is there any other way to validate the token and get an access token from the server, or should I completely change the authentication procedure on Android?
As far as I can tell: Yes, you need an access token from the server. If I understand this correctly, a webapp is already authenticated via Oauth on your backend, so the procedure is similar here: Load the user with the google-ID and generate a token. In my application I used a JWT which is valid for 30 days. If the token expires, the Google authentication in the app is usually still valid, so the token can be renewed using the Google ID. With Oauth you can also send a refresh-token directly.
It is important that the app always checks the Google authentication first and only in a second step that of the backend.
For the Authentication process on the backend u may need to manually implement a dedicated securityConfiguration for this. Have a look at the jhipster project, they implemented a custom jwt-authentication which may give you an idea how it works.

Office 365 Social APIs Access Denied

I am working with Office 365 and the Sharepoint 2013 APIs. I am using Azure AD to authenticate a user and have a test application setup inside AAD that has all the delegated permissions set to enabled in the configure tab for Sharepoint 2013. I am making these calls from a native android application and have been able to successfully authenticate with Microsoft's ADAL(ActiveDirectoryAuthenticationLibrary) using this oauth authority url: https://login.windows.net//oauth2/token?api-version=1.0. I then access my test share point site and get back a list with https:////_api/Web/Lists?getByTitle('')/Items using the Oauth token that I received from back from using ADAL. That all works well and fine, but when I try to access the Social APIs with the same token process I get a 401 Unauthorized. The url that I am using to get the current users information is: https:////_api/social.following/my. What am I doing wrong that is causing the lists api work and the social api to fail? Any help is greatly appreciated!
Are you requesting a new token for the resource before calling that resource?
The ADAL library must acquire a new Access token for each resource you are requesting. Our library automatically does the redemption of the refresh token for the new Access token if you call acquireToken() using the new resource endpoint. This is hinted at in the API docuemtation.
Example:
mAuthContext = new AuthenticationContext(ToDoActivity.this, Constants.AUTHORITY_URL,
false);
mAuthContext.acquireToken(activity, resource, clientId, redirectUri, loginHint, prompt, extraQueryParameters, callback)
//do work with the token
// now get token for new_resource
mAuthContext.acquireToken(activity, new_resource, clientId, redirectUri, loginHint, prompt, extraQueryParameters, callback)
You can use an example here which will help you see how this can be done: https://github.com/AzureADSamples/NativeClient-Android

accountmanager refresh token(offline access)

I use google login through account manager in my android app. I can get accesstoken which I send to server and server can create/login new user. Accesstoken is valid only 3600seconds. Problem is that server can not update user's info after this time expires. Web app requires check user's info periodically.
How can I get authentication token and refresh token from android account manager so than server can use refresh token to update data periodically? I don't want use login through webview in android app.
Thanks
This is now possible: https://developers.google.com/+/mobile/android/sign-in#server-side_access_for_your_app
You request a one-time authorisation code, send it to your server and your server exchanges it for an access token and refresh token.
Currently you can't, which I'm sure is not the answer you're hoping for, sorry about that! If you have a web sign in, you can use the hybrid flow to get a refresh token on the server as well (see https://developers.google.com/+/web/signin/server-side-flow), but there's no way of retrieving a code as part of the Android or iOS flows.
If this is something that you need for you use case, could you file a feature request on here: https://code.google.com/p/google-plus-platform/issues - we are actively looking at the number of stars on that to gauge demand for various features.
Google Authorization process through account manager:
Email id can be got from
AccountManager accountManager = AccountManager.get(getApplicationContext());
Account[] accounts = accountManager.getAccountsByType("com.google");
String emailID = accounts[0].name; // you can retrieve using google account chooser way also
These lines should be run in separate token(not in UI thread).
String scope = "oauth2:https://www.googleapis.com/auth/userinfo.profile https://gdata.youtube.com";
String accessToken = GoogleAuthUtil.getToken(mContext, emailID, scope);
save the the accessToken and use for your api access.
After one hour (i.e. 3600 seconds), we need to refresh the access token. But now google is not supporting access after one hour. We have to restart the application and use the following lines to get access token.
String scope = "oauth2:https://www.googleapis.com/auth/userinfo.profile https://gdata.youtube.com";
String accessToken = GoogleAuthUtil.getToken(mContext, emailID, scope);
This background thread will always run in background in while loop

Android subscription and Google API

I'm trying to use the new Android subscription system from Google Play into my application (I already had in-app billing working fine). I have successfully done the subscription billing, but I now want to retrieve informations about this subscription by using the google apis as indicated in the android documentation (http://developer.android.com/guide/market/billing/billing_subscriptions.html).
I want my service to be able to do the API call to retrieve these informations, but I have problems with authentication (with oauth2). So far, this is what I do (in my php service) :
require_once 'google-api-php-client/src/apiClient.php'
const SERVICE_ACCOUNT_NAME = 'email from services account access';
$key = 'content of my private key retrieved from services account access';
$client = new apiClient();
$cred = new apiAssertionCredentials(SERVICE_ACCOUNT_NAME, array('https://www.googleapis.com/auth/androidpublisher'), $key);
$assertion = $cred->generateAssertion(); // This generate my encrypted JWT
I then try to retrieve the access token with this JWT object. The problem is that when I use the access token given I got the error that the developer account does not own the application, which is not true.
(I know this is not the way to do it, but I just wanted to retrieve the access_token using the JWT to understand why it is not working, if I do it as indicated in the google apis documentation it is not working too).
I need to do this API call from a server, so no end-user has to be involved (no manual consent).
I had the same issue, and ultimately discovered that as of right now service accounts can not access the Play API.
I'm not sure when Google is planning on fixing this but you can get around this by creating a web app client ID and setting up a basic login page to first generate a code using the new web app Client data and going to $client->createAuthUrl():
$client = new apiClient();
$key = file_get_contents(KEY_FILE);
$client->setClientId(CLIENT_ID);
$client->setClientSecret(CLIENT_SECRET);
$client->setRedirectUri(MY_WEBAPP_URL);
$client->setDeveloperKey($key);
$client->setScopes(array('https://www.googleapis.com/auth/androidpublisher'));
$authUrl = $client->createAuthUrl();
print "<a class='login' href='$authUrl'>Connect Me!</a>";
This should take you to a Google login page where you should log in with the developer account. When you authorize the app, it will take you back to your web app URL as defined when you set up the client ID with a CODE as a get parameter. You can use to generate a token (and more importantly, a refresh token) like so:
$url = 'https://accounts.google.com/o/oauth2/token';
$fields = array(
'grant_type'=>'authorization_code',
'code'=>$code,
'client_id'=>CLIENT_ID,
'client_secret'=>CLIENT_SECRET,
'redirect_uri'=>MY_WEBAPP_URL
);
// cURL call to OAuth URL with $fields sent as POST
This should return you JSON data with a refresh token. Save this token and use it to make another call whenever you need to generate an access token. You will essentially run the same code you did to get the refresh token, but with different fields:
$fields = array(
'grant_type'=>'refresh_token',
'refresh_token'=>$refresh_token,
'client_id'=>CLIENT_ID,
'client_secret'=>CLIENT_SECRET,
);
This will give you an access token you can use to get purchase data from the following URL:
https://www.googleapis.com/androidpublisher/v1/applications/[PACKAGE]/subscriptions/[SKU]/purchases/[PURCHASE_TOKEN]?access_token=[ACCESS_TOKEN]
The trick is getting the refresh token, once you have that the rest should be pretty straightforward.
I`ve got the same problem. It occurs because you authorize user in Google API who does not own the application and try to get data which belows to your app.
In this topic it is well described. http://support.google.com/googleplay/android-developer/bin/answer.py?hl=en&answer=2528691&topic=16285&ctx=topic
You should authorize by OAuth2 the owner of application, and then use Google API with obtained token.

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