Requesting more than one oauth2 scope through AccountManager in Android - android

I'm in a situation where I need to request access tokens for two scopes (from my android application), https://www.googleapis.com/auth/userinfo.email and https://www.googleapis.com/auth/userinfo.userinfo
I would like to get both permissions on a single call to getAuthToken, but can't figure out the string to pass in the authTokenType parameter. I tried several reasonable combinations with no positive results :(
Has anyone solved this issue? Is it possible?

I was having the same issue. Shah is almost right, but his scope string is wrong. It should be
"oauth2:<scope_url> <scope_url>"
not
"oauth2:<scope_url> oauth2:<scope_url>"

If you need multiple OAuth 2.0 scopes, use a space-separated list.
oauth2:https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.userinfo
You asked for sample code, so have a look at the Google Docs Upload Sample application, and in this application have look at the authentication flow done in this sample Android screen (ignore that it's about Google Docs, it still authorizes first). You can get the whole application and run it in an emulator with Google APIs present or run it on your phone. The authorization workflow starts with the buttonAuthorize click, Authorize() and you are specifically interested in this method:
private void gotAccount(Account account)
{
Bundle options = new Bundle();
accountManager.getAuthToken(
account, // Account retrieved using getAccountsByType()
"oauth2:https://www.googleapis.com/auth/userinfo.email oauth2:https://www.googleapis.com/auth/userinfo.userinfo", // Auth scope
//"writely", // Auth scope, doesn't work :(
options, // Authenticator-specific options
this, // Your activity
new OnTokenAcquired(), // Callback called when a token is successfully acquired
null); // Callback called if an error occurs
}
The user gets this access request screen:
Note that this is using the 'local' OAuth2 mechanism, not opening a web browser, but using the authentication provided when you first activated the Android phone.
Also note that the user sees the full URL of the scope instead of a friendly name, I haven't found a way around this and if you do find out it would be great if you could share the answer.

Related

Android Kotlin net.openid:appauth - capturing token after firing intent with getAuthorizationRequestIntent

I am trying to make sense on how to use android's AppAuth library based on the different examples that showcase different use cases of this library. I haven't managed to grasp what it requires for it to work. I also had a look at their docs
my approach:
Call the fetchFromIssuer method, this method is passed the discovery doc uri, which when called is successful. From this discovery doc, i use the authorisation endpoint and token endpoint to configure a new service like so:
val authServConfig = AuthorizationServiceConfiguration(
authEndpoint /* from discovery doc */,
tokenEndpoint /* from discovery doc */,
)
More configuration is performed, then when the intent is fired and a browser is launched to enter the details, once these details are entered and sign in is performed, I am redirected back to the app launch screen. At this point I don't know how to go about intercepting this token or whether or not the authentication was succesfull.
the code for the intent:
val authServ = AuthorizationService(applicationContext)
try {
val authIntent = authServ.getAuthorizationRequestIntent(authRequest)
startActivity(authIntent)
The intent is successful but the redirect after authenticating I don't know where it goes.
The examples I have come across with this app have invoved:
downloading an example project which when downloaded and launched using android studio, error upon error, nothing works.
I chose to work with this example but again no luck: codelabs
With AppAuth, if you have not worked with token authorisation comfortably you may find it somewhat challenging to use this library. I also have to say it does some heavy lifting and gives you some mechanisms out of the box to work with.
Configure the library as recommended or how you want to use it.
My approach so far is to have one wrapper class that will manage the instances for the Service and State (for now).
The part were I was stuck is because I was missing the RedirectUriReceiverActivity. It is this activity's intent result you get to work with in onActivityResult. It is in here you handle the response from the browser intent (After user successfully acquires a token).
Also don't forget to handle when the user chooses to dismiss the intent.
Regarding the refresh token. The library has performActionWithFreshTokens method on authsate.

Authentication with Dropbox Api V2 [duplicate]

I've just started out and I'm following this tutorial
https://www.dropbox.com/developers/documentation/java#tutorial
But there's no login. Nothing asks you for a username, password. That means I can't actually get a GUI that every app with "Share to Dropbox" option has.
Am I stuck with one account? Do I have to find a way to get a person's ACCESS_TOKEN or is there a more elegant GUI solution out there(like with Google Drive and their intentsenders)?
To use the Dropbox API v2 in Android, you should use the API v2 Java SDK. There's an example Android app that uses it included with the SDK. You should refer to that as an example of how to implement the app authorization flow, which is accomplished via OAuth 2. That requires the user to authorize your app with Dropbox, by signing in to Dropbox if necessary. After that, your app can store and re-use the resulting access token for that user, as the example does here.
Implementing it that way allows any user to connect their Dropbox account to your app. You can also handle multiple accounts per instance of your app if you want.
Unfortunately, there isn't much out there in terms of documentation for this flow. Here is how I was able to successfully authenticate users. First, you want to launch the authentication flow with Dropbox's auth activity:
import com.dropbox.core.android.Auth
....
Auth.startOAuth2Authentication(context, context.getString(R.string.dbx_api_app_key))
After a user has successfully authenticated, call the following method in the onResume method of the activity you started the Dropbox activity from:
#Override
public void onResume() {
super.onResume();
String token = Auth.getOAuth2Token()
}
The token that you receive here should be used when you create your instance of the DbxClientV2 like so:
DbxRequestConfig requestConfig = DbxRequestConfig.newBuilder(MyUtils.getVersionText(context))
.withHttpRequestor(OkHttp3Requestor(OkHttp3Requestor.defaultOkHttpClient()))
.build()
DbxClientV2 dbxClient = DbxClientV2(requestConfig, accessToken)
You'll also need the following dependencies in your build.gradle file:
implementation 'com.squareup.okhttp:okhttp:2.7.5'
implementation 'com.squareup.okhttp3:okhttp:3.7.0'

Authorize user on Google website in WebView via dialog

For example, user is navigating to google.com in WebView.
Is it possible to authorize him there via Google Account Picker (something like described here https://developers.google.com/android/guides/http-auth) to simplify authorization instead of manually logging in via web form?
Android Web browsers (for example, Google Chrome) are authorizing user via this method).
Part I: Using the Google Plus Services API
If I understand your question correctly, you may be able to achieve what you are trying to do using the Google Plus Services API.
You create your GoogleSignInOptions and then create your GoogleApiClient using these sign-in options. From there, you use the Auth.GoogleSignInApi.getSignInIntent with your GoogleApiClient as the parameter.
This intent should launch a SignInIntent that presents the Google account picker (that will include accounts that have been accessed on the device previously, and the ability to add another account).
Once you get back the GoogleSignInResult, you can verify that the user was authenticated and then create the authentication flow as you would otherwise.
Even included in the Android SDK is the Google SignInButton, which you can use right in your layout instead of having to create a custom button for the sign-in.
Part II: Using WebViewClient
Now, if you are trying to use a WebView to authenticate them, your best bet is to extend the WebViewClient class.
Things you will need: clientId, clientSecret, and clientScope (all of these details will be given for you when you create your application in the Google Developer Console)
First things first, your URL to authorize will probably be as follows: https://accounts.google.com/o/oauth2/auth?response_type=code&clientId={your client id}&state={SOMESTATEINFO}&access_type=offline (access type if you want offline access). This should be the initial URL of your WebView
Next, you will want to modify your extended WebViewClient class. What you will want to do is override the shouldOverrideUrlLoading(WebView webView, String url) method to listen for your redirectURL. Probably the easiest thing to do is to use url.startsWith(<your redirect URL>) to detect this. You can then parse the response. If your response contains error, then it means something went wrong. Otherwise, you should get back two fields in the URL: code and state. If you do not get error back, then return true for shouldOverrideUrlLoading.
Once you get your code, you can create a new GoogleAuthorizationCodeFlow, using your client, scopes, and secrets.
Once you have your flow, you will need a GoogleTokenResponse, which you will be able to get using the code obtained above for your authorization code, using GoogleTokenResponse response = flow.newTokenResponse(<code>).setRedirectUri(<redirectUri>).execute().
Once you have done this, and you have your response, you can get your Credential using flow.createAndStoreCredential(response, null).
And voila, using this Credential, you can authenticate your calls.
Caveats I have not been able to get the WebView to recognize accounts that have been signed into on other web browsers, so the account picker may only show the accounts that have been signed into on the app-specific WebView.
tl;dr It is possible to do this with a WebView and WebViewClient, but it's messy and a little bit more roundabout than using the Google Plus Services API.
This example better illustrates the authorization flow/credential stuff once you get the authorization code and such.
And here's some documentation on the WebViewClient that may be useful as well.
Hope this helps point you in the right direction!

Request public Google+ profile data

I'm searching the PlayServices equivalent of this call:
https://www.googleapis.com/plus/v1/people/<some_user_id>?key=<your_api_key>
The call above is documentation of the call above is here: https://developers.google.com/+/web/api/rest/latest/people/get
However this is a web API call and my keys are restricted to a limited set of IPs. I think it would be a bad idea to put that key in code. Do you think the same?
Just as a side note I would like get the data without "authorization". I mean I authenticate with my key, but I don't want to ask the user. With the HTTP call above this is possible, so what is the Android SDK equivalent? I'm not asking how to do the GoogleApiClient stuff I have this already working. I just want to know the right call of the plus API.
If there is nothing similar do you know how to authenticate myself at the rest service with my packagename and signature?
In summary I just want to know the (first and last) name of the local G+ accounts like in the Google Foto app.
To load a specific Google+ profile in Android use the load method for com.google.android.gms.plus.People.
public abstract PendingResult<People.LoadPeopleResult> load (GoogleApiClient googleApiClient, String... personIds)

Mobile facebook login - credentials provided by app settings

I managed to post status updates on facebook walls and log in via the following code:
facebook.authorize(this,
new String[]{ "publish_checkins", "publish_stream"},
new DialogListener() { /*crazy stuff here*/ }
);
My problem is the very first time logging in. Because it seems that the facebook is is not supporting logins from test accounts I can't talk about SSO but consider the "normal", web based, login screen popping up.
Is there a way get around this screen and let the application perform a login via username/email/password combination - provided the user is willing to handle this data to the applications.
E.g. something like facebook.authorize(this, permArray, userName, password,
I ask because I'm not sure if this is even possible at all, read: if fb API is providing hooks for this. I can imagine it is kinda security concern and thereby switched off.
In this case it would be cool if someone could provide a link to some documentation listing all possible login methods (not "all" but the important ones for smartphones) - this would definitely be helpful in the next meeting.
The main document one should work with, in my opinion, when implementing the Authentication part for FB, is their tutorial (for Android this one) - seems you're familiar with it. There you can see how facebook expects you to get logged in.
And here (for Android here) is the list of the methods they provide for these purposes.
To be shorter, NO, they don't have some simple function, which would allow you to do something you mentioned. Looks like you must use browser/their official app to login, in order to save cookies there; or you can use UIWebView to save them in your app.
I worked with FaceBook API some time ago and I didn't like it a lot. Perhaps this is because of the changes they've been doing lately in the API, but their documentation seems to be just immature; not speaking about their official example client (HackBook), which just doesn't work as expected (e.g. post video on the wall doesn't work).
Somehow even after reading carefully their documentation I had quite a lot of questions like what can be done with this API and what's forbidden at all.
Hope this helps!

Categories

Resources