Is it possible to authenticate user manually with oauth2 - android

I want to authenticate a user with oauth2 to access google drive. I can get the access token required when using AccountManager to retrieve an account and then get the token with:
mgr.blockingGetAuthToken(account, ApiConst.DRIVE_AUTH_SCOPE, true);
But I want the user to be able to authenticate by providing username and password instead of using the account added to the phone. Is this possible?
EDIT
So I have tried to implement the authorization in a WebView. I followed this example. I have extracted the code request parameter but the code used to retrieve the access token seems to be deprecated and not compatible with the packages used by Google Drive SDK. This is the code used to retrieve the access token in the example:
AccessTokenResponse accessTokenResponse = new GoogleAuthorizationCodeGrant(new NetHttpTransport(),
new JacksonFactory(),
OAuth2ClientCredentials.CLIENT_ID,
OAuth2ClientCredentials.CLIENT_SECRET,
code,
OAuth2ClientCredentials.REDIRECT_URI).execute();
Can this be done in some other way or should I just give up?

If you are in Android, you don't nedd to do all that stuff to authenticate a user.
Just use "GoogleAccountCredential" object to set the user's account:
GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(this, scopes);
credential.setSelectedAccountName(theGoogleAccount);
Remember that for select user's account you need:
startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT);
Then you'll be able to initialize Drive:
Drive service = new Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), credential).build();
Greetings.

Related

Authorize YouTube Data API for Android via OAuth2

I am trying to authorize with OAuth2 to use YouTube data API. I want to write a simple client for Android to have a possibility, for example, get lists of user subscriptions, playlist etc.
The problem is that each method I try (e.g. HTTP requests like https://www.googleapis.com/youtube/v3/subscriptions or YouTube library com.google.apis:google-api-services-youtube:v3-rev120-1.19.0), I get the same error:
401 Invalid Credentials
I do these steps:
Register app in Google's console. Enable YouTube Data API. Create OAuth credentials with my app package name and keystore.
Create Android API Key.
And here I have a lot of questions.
To have a possibility to get user subscriptions etc. do I have to register the app with OAuth2 credentials AND (?) Register API Key?
How can I use client_id and other data that is in client_secrets.json? How can I use this client_secrets.json at all? Do I need download it, and how to use it?
Because when I saw sample code, for example this:
GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(context.getApplicationContext(), Arrays.asList(SCOPES));
credential.setSelectedAccountName(accountName);
YouTube youtube = new YouTube.Builder(new NetHttpTransport(),
new JacksonFactory(), credential).setApplicationName(context.getString(R.string.app_name)).build();
Or used AccountManager and get token
accountManager.getAuthToken(userAccount, "oauth2:" + mScope, null, (Activity) mContext,
new OnTokenAcquired(), null);
where mScope="https://gdata.youtube.com"
and then use it this way
https://www.googleapis.com/youtube/v3/subscriptions?part=snippet&maxResults=10&mine=true&key={here is my key}&access_token= ya29.bgJa5J8LHHu0Mu3P87mbPY9gfhSFzWUHh8gCw022FC6yfMO6GfVHveYr_BG1-HnWF-jpd-IDcGGVrF3gEf4UhSHPSrV76RAwqd4V17ixn72s1Xl6a0wQ4FVDz3cEZjUEN80o
I get the same authError error every time (in short):
"code": 401,
"message": "Invalid Credentials"
What I am doing wrong? How to use client_id in variant 1 and 2. Is it necessary? Because I think it is the reason why it does not work.

Google+ and AppEngine Authentication

I have an Android application with Google+ already setup and I was wondering if I could use this connection to authenticate with Google AppEngine endpoints.
Google sample code is:
settings = getSharedPreferences(TAG, 0);
credential = GoogleAccountCredential.usingAudience(this, ClientCredentials.AUDIENCE);
setAccountName(settings.getString(PREF_ACCOUNT_NAME, null));
Tictactoe.Builder builder = new Tictactoe.Builder(
AndroidHttp.newCompatibleTransport(), new GsonFactory(),
credential);
service = builder.build();
So this is fine, but I'm doing authentication all over again. Can I leverage the PlusClient in any way to avoid creating further credentials?
Thanks
You can do the below steps to utilise your google plus sign to authenticate users for Google AppEngine endpoints:
1, Get the account name using google plus which will be in the step
String accountName = mPlusClient.getAccountName();
Now you dont have to use the account picker provided in the sample code as you go the account name through google plus
2, Save the account name from your above step to the sharedpreferences and to credential:
private void setAccountName(String accountName) {
SharedPreferences.Editor editor = settings.edit();
editor.putString(PREF_ACCOUNT_NAME, accountName);
editor.commit();
credential.setAccountName(accountName);
this.accountName = accountName;
}
3, Create a client id for a web app to be used as audience. I guess this should be in the same project in api console where you have already created a client id for your android app. Set this web app client id as ClientCredentials.AUDIENCE value.
4,In your app engine project with cloud endpoints, for the allowed_client_ids argument of the #endpoints.api decorator or #endpoints.method decorator, supply both Android client ID and web client ID. You must also set the audiences argument for the #endpoints.api decorator to the web client ID.
5, In your android app, use the account name and audience details to create a google credentials object and pass it to your service object to call the required cloud endpoint
6, You can also add a user check in your app engine code to ensure a valid user is accessing
from google.appengine.ext import endpoints
current_user = endpoints.get_current_user()
if raise_unauthorized and current_user is None:
raise endpoints.UnauthorizedException('Invalid token.')
Since you have google+, you can also look up the emailid using the userinfo.email scope as given here . Also check these 2 posts for useful info : GCE with G+ and Oauth on GAE with google play services

Use Android AccountManager to do AppEngine login through UserService

I'm using Google AppEngine, and I'm using their UserService class to handle user accounts and logging in. I don't need to access any information about their account - I'm just using it to differentiate users.
Now the website is mostly just a backend. I'm using an Android app for the frontend. I know you can access Google user accounts on the device using the AccountManager. It's definitely the safest way to get a user to log in. And I got that much to work.
Where I'm stuck is passing the login information from the Android app to the AppEngine website. From what I've ready I should be using OAuth, and I see the walkthrough here for using it with Google APIs, but I don't need to access an API, just to log in. I've been able to acquire an Authentication Token in the app, but I'm not sure how to pass it to the website, or if that's even the right direction. Should I be using a specific OAuth login on the server, like this guy?
Any help would be greatly appreciated!
Here's the relevant code:
Server (GAE):
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
if (user == null) {
resp.sendRedirect(userService.createLoginURL(req.getRequestURI()));
return;
}
Client (Android):
AccountManager am = AccountManager.get(this);
Account[] accounts = am.getAccountsByType("com.google");
Bundle options = new Bundle();
am.getAuthToken(
accounts[0], // Account retrieved using getAccountsByType()
"Manage your tasks", // Auth scope
options, // Authenticator-specific options
this, // Your activity
new OnTokenAcquired(), // Callback called when a token is successfully acquired
new Handler(new OnError()));
//Now what!?
This blog post covered exactly what I needed.
For two alternate (and in my opinion less than ideal) solutions, check out this thread: Webservice credentials - OpenID/Android AccountManager?

How can I access the Google account user_id?

I'd like to access the user's Google account user_id for authentication, but I don't see any mention of this in the AccountManager.
How can my app request the user_id?
Now that Google Play Services is available, you can use it to request the user's permission to access the https://www.googleapis.com/auth/userinfo.profile scope and, with the resulting access token, make a request to https://www.googleapis.com/oauth2/v1/userinfo?access_token={accessToken} to get their user ID.
You will need to use the Android AccountManager's getAuthToken API until Google Play services is released.
Here's an example of how you can use getAuthToken to obtain an access_token: https://stackoverflow.com/a/10988589/313790
Check out Google's AccountManager example for the Tasks API.
Once you have an access token, you then instead of using the Tasks library, use the oauth2 library of google-api-java-client to request a Userinfo object like in this example:
Oauth2 oauth2 = new Oauth2.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName("Google-OAuth2Sample/1.0").build();
Userinfo userinfo = oauth2.userinfo().get().execute();
String userId = userinfo.getId();

Using authToken for Google Health Data

We have developed and published an app for Google Health. Now we want to avoid every time logging into the gmail account by asking username and password.
So as to do this i have heard that I can have following options.
1. OAuth
2. Account Manager
3.
The problem with OAuth is that it will go via Android -> Web App -> Health path so i will need to develop an web app as well which we dont wish to do it right now.
So I am trying to use Account Manager, here is my code with which I could get list of accounts and an valid authToken for the selected account.
AccountManager mgr = AccountManager.get(getApplicationContext());
System.out.println("Got account manager");
Account[] accts = mgr.getAccounts();
}
Account acct = accts[0];
AccountManagerFuture<Bundle> accountManagerFuture = mgr.getAuthToken(acct, "android", null, this, null, null);
Bundle authTokenBundle = accountManagerFuture.getResult();
System.out.println("Account name "+accts[0].name);
String authToken = authTokenBundle.get(AccountManager.KEY_AUTHTOKEN).toString();
System.out.println("Got token:"+authToken);
But now I am confused about how to use this token to access the health data.
For getting the demographic feed we used the following code,where we explicitly made user to login into our application.
String queryURL = "https://www.google.com/health/feeds/profile/ui/" + profileId +"/-/DEMOGRAPHICS";
getDemoGrInfoQuery = new Query(new URL(queryURL));
Feed dempGrResultFeed;
globals = new Globals();
dempGrResultFeed = healthService.query(getDemoGrInfoQuery, Feed.class);
And thus we used to get the Feed using the URL.
And now I want to skip the login process and use the above authToken for retrieving the feed. How can this be done?
Any help would be really appreciated!!!
Thanks in advance,
As the standard OAuth procedure is supposed to work, you open the OAuth URL in a WebView (or anything similar) with all the required parameters, users provide Google (not your app) with their user name and password, then google gives you a token which you can use for your future communications.
This way the user doesn't have to give you their login credentials. They give it only to google, and google gives you a token which will authenticate your app every time you use it.
I think you should be good to go with this, since it requires you to open a WebView only once, unless the user logs out of google using your application or denies access to your application.
After getting the token, you just start polling google with that token and never ask user for their login credentials. quite seamless.
UPDATE
After our conversation in chat, let me tell you that you'll have to register an application with google, which will give you an appID, this appID will be used by your Android app to tell google that it is requesting permission on behalf of the Application which this appID refers to.
UPDATE 2
open the Google OAUth with all the parameters, google will give you a code
use that code and create a POST request again to google, and google will now return a long lasting AccessToken
You can then use this AccessToken in all your future communications

Categories

Resources