Google OAuth2 re-authorization is missing permissions on the consent page - google-api

When I force a user to re-authorize my application a second time, using approval_prompt=force, how can I get Google to show the user the entire list of permissions my app is requesting?
Details:
I have a web application that requests a set of Google API permissions, including access_type=offline. The first time I approve it, it shows the correct consent page, listing all the permissions, which looks like:
Later, I send the user back to authorize with Google, with the same parameters. The second time, it only shows "Have offline access":
Why does it not show the users all the permissions? Is there a way to force it to ask the user for all the permissions a second time? Why does it now show "Have offline access" the first time?
Our users find it confusing that our app is not asking for any actual permissions, so I'd rather just show the first approval screen again.
The full parameters for the request I am making are as follows. URL:
https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force&client_id=1039955146864.apps.googleusercontent.com&redirect_uri=http://localhost:8081/sync/google/callback&response_type=code&scope=openid%20email%20https://www.googleapis.com/auth/admin.directory.group.readonly%20https://www.googleapis.com/auth/admin.directory.group.member.readonly%20https://www.googleapis.com/auth/admin.directory.user.readonly&state=480704597031619284232891277399900450622
Parameters broken out:
access_type:offline
approval_prompt:force
client_id:1039955146864.apps.googleusercontent.com
redirect_uri:http://localhost:8081/sync/google/callback
response_type:code
scope:openid email https://www.googleapis.com/auth/admin.directory.group.readonly https://www.googleapis.com/auth/admin.directory.group.member.readonly https://www.googleapis.com/auth/admin.directory.user.readonly
state:480704597031619284232891277399900450622

We launched incremental auth and this is the working as designed.
http://googleplusplatform.blogspot.com/2013/12/google-sign-in-improvements11.html
The idea is if a user has already granted the permissions to an app, there is no need to show the same permissions and ask the user to approve.
If you write your application properly then this situation should not arise. If you request an offline code (refresh token) and store it on your backend, you shouldn't be asking for it again unless if you need to get some new scopes/permissions. You should use the refresh token that you have stored in the future. If you only need the access token when the user is on your site, you can use other flows to request an access token without user seeing an approval page.

You have to revoke the access token and log out. Then if you go to sign in process, It will show the permission.
public static void RevokeAcess(String accessOrRefreshToken) throws ClientProtocolException, IOException
{
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("https://accounts.google.com/o/oauth2/revoke?token="+accessOrRefreshToken);
client.execute(post);
}
This network process should be called in non ui thread or asyntask

Related

Sending automated emails using Gmail API with Java and Oauth authentication

I have a web app which sends emails (gmail) in name of my users
When a user registers, she supplies gmail account and password. Also she has to enable access for Less Secure Apps (I recommend to create a new account for this)
Then I can open a gmail session
session = Session.getInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user.getEmail(), user.getPassword());
}
});
and send emails on her behalf.
Unfortunately this is going to stop working next 30th May, when Google will allow only OAUTH2 access
I have followed Java Quickstart for Gmail API and I have code up and running for sending emails with OAUTH2: enable gmail api, create an application on google cloud platform, grant send permission, oauth2 client id credential created...
The problem I have is I can't see a way to automatize this task because when creating an authorized credential, a consent screen displays on browser and you have to select the account to be granted manually (maybe because my app in google cloud platform is still pending to be reviewed)
Is there a way to infer the gmail account you want to access from the credentials file (client_secret.json)? Is there a way to automatize this?
No, or yes. It depends.
The whole point of OAuth2 is to improve security by working with authorization tokens rather than asking for user credentials. To do this the user has to consent to the app's access request, and thus the OAuth consent screen cannot be bypassed. This is
explained in Google's documentation. It's not related to your app's review status but rather it's the way OAuth works.
You can still work in a similar way, though . Instead of asking for username and password upon the user's registration you can redirect them to the OAuth consent screen so they can authorize your app. Make sure that your app is requesting offline access type and then you can retrieve an access_token and a refresh_token. These will essentially work as your credentials and you can use the refresh token to generate new access tokens when needed without having the user go through the consent screen each time.
The refresh token doesn't have a "natural" expiration so you can keep using it indefinitely, but there are a few scenarios where it will become invalid, such as it not being used for six months, the user changing passwords (if using Gmail scopes), the user manually revoking access, etc. In these cases you will need to direct them to the consent screen again to reauthorize your app.
In this sense, your app can still work automatically without user input except the initial setup, which you already had to deal with when they supplied you with their credentials. The refresh token expiration can even be compared to what you had to do when the users changed their passwords in your current workflow.
One exception to this are service accounts. If you and your users are part of a Google Workspace domain you can delegate domain-wide access to it, then the service account will be able to access user data without any manual input. Of course, this is because as the domain administrator you pretty much own all the accounts under it. But if you're working with a publicly available application you will have to deal with the limitations I mentioned above.
Sources:
Google's auth overview
Using OAuth 2.0 to access Google APIs
OAuth 2.0 for web applications
The OAuth consent screen

How does Google One-Tap manage my refresh tokens? How does it differ from GAPI?

In the documents of Google One-Tap sign in, it says:
Returning users are signed in automatically, even when they switch devices or platforms, or after their session expires.
Question 1:
But it doesn't say anywhere how it does this? Is the user refresh token saved in the browser's cache? How can it then auto log in a user cross devices?
Question 2: The reason I ask is because I have a setup where I initialize the Google API client for JavaScript ("GAPI"). The GAPI library also automatically logs in a user whenever the client is "initialised" through gapi.client.init().
Now the problem is that after I have added the Google One-Tap code (Or should I say "YOLO code"? : ) my user gets logged in through One-Tap and also through GAPI. I can prevent this by not initializing the GAPI client, but I don't think that's wise, because I thought this whole library is built to manage my refresh tokens etc. Is my understanding correct that One-Tap does exactly the same and in case I only want to Authenticate users I do not need the GAPI client anymore?
Really, which library does a better job at managing my refresh tokens? And how do they differ? I'm clueless...
The way I implemented my login is the following:
Try to login in the user first using gapi.auth2. Maybe the user was previously signed into the site.
If can't login user automatically, then use googleyolo to try to find existing user accounts.
If no existing accounts, then present a signin button for user to signin.
I can give you some code snippet if you need.
To answer your questions.
#1, the credential is stored within the browser/device. If the user has never signed into google in a device, then yolo won't be able to sign in the user.
#2. googleyolo will also login the user, the difference is that it will give the account selector even if there's only one user to select (it will automatically login the user if there's only one). gapi simply sign in the user without showing anything.

Parse.com login using magic link

After Parse.com have introduced new revocable session that gets destroyed when a user logs out, is it possible to build a reliable login process using "magic links", ie. a user receives an email including a link, and gets logged in in a web browser after clicking that link?
Previously, sessions in Parse were long lived and implementing a magic link login process was a matter of providing the user with his/her session token and having the client call Parse.User.become(<sessionToken>).
This approach will fail with new revocable session if a user is not already signed in to the Parse server when generating and clicking a magic link, since there will not be any session to give the user that he/she can use in the call to Parse.User.become().
Any clarification if this is possible to accomplish this with the new more secure type of revocable sessions in Parse, or suggestions on how to achieve this, are welcome.

How can I setup Google Oauth to allow login using an alternate Google account?

I made a members-only site that uses Google oauth2 to authorise users. The site is built with the Laravel framework and Artdarek's oath library.
When the authorization callback comes from Google, I lookup the user record in the DB by email and proceed to the protected page if the record exists, otherwise to a register page.
The problem is some of our members use two Google accounts. One user registered via his primary account (e.ge. a#gmail.com). The next day he returned and mistakenly tried to login with b#gmail.com. Naturally the system showed him the registration page. From that time on each time he visits the site the authentication mechanism sees him using his second (unwanted) set of credentials.
To resolve this one case I instructed him to logout of all accounts (on both sides), clear cookies and start from scratch but this is not a practical solution for all users. In same cases even this measure does not seem to correct the problem.
How can I solve this case? What is the right way to request oauth authentication and get them back from the right account? Can I force Google to ask the user with which account to proceed?
Google will automatically ask the user which account they want on an oauth request if they enable the account chooser.
I have logged into my Google Apps and my Google account, so for me on an oauth request, I get the following prompt:
In order to do the same for your user, they have to click "Stay signed in", but of course this is not advisable for public computers.
Beyond the above, I'm afraid not much can be done. - if they logged in with a#gmail.com at that time, these are the credentials you will receive.
They way I solve this problem is to have a field where the customer can add additional emails, and select one that is primary. I will then inspect against these emails when a request comes in to avoid duplicate user accounts.

What is the use of infinite session in facebook?

A session token is given to the user when he starts running a facebook application, as long as this token is not stolen, other people cannot impersonate him. To increase security, a new token is also generated again when it has expired or has been cleared.
So what is the problem here? Why do people want infinite session token in facebook?
How is it useful to both developers and end-users of facebook applications?
It's now called "offline_access". You're right in that most applications don't need this permission; however, occasionally an app may want to do some processing on behalf of the user while the user isn't present. For example, there are some blogging apps like posterous.com that allow you to email your blog posts - and they may want to publish without asking each time. For those, it's appropriate to ask for the extended perm.
Here's more information about how to request the permission:
https://developers.facebook.com/docs/guides/policy/examples_and_explanations/Extended_Permissions/
Why do people want infinite session
token in facebook?
So that when they exit their browser and restart it, they don't have to type in the username and password again. The authentication is still there so they can just simply start facebooking.

Resources