Is getting another user's ID token possible? - google-oauth

I'm working on a web app where all users sign in using their Google account, using Google's OAuth2 API. I'm using ScribeJava to take care of the OAuth details.
I'm currently using the "sub" field of the user's ID token as their primary key in my database. When a new user logs in for the first time, their "sub" is stored for future logins.
I'm looking for a way for an administrator to add a user before they first log in - however, since I don't have the new user's "sub", I can't just add them to the database. Is there a way to use Google's API to look up another user's ID token (or at least the "sub" field) using their email address? Is there a better primary key that makes this easier?

Let me start by saying using the Sub id is probably a really good idea. However there is no way for you to get a users sub id from their email address. That information just isn't available until a user logs in as its part of the authentication Open Id connect claims.
Sorry but what you want to do isnt possible.

Related

Authentication using oauth2

I am trying to create web-forum with user authentication, using Github and Google. I've already managed to get user information with access token, like login, email and etc. But I don't get the workflow for authenticating this user in my database.
In order for user to register, he need to provide email, login and password. All the examples and tutorials I saw, was stopping at the sessions and that's it.
My website has database with posts and comments, and to fetch, for example, user's created posts, I need to get the user id, then I will lookup in the database. I thought, maybe, I can use access token as a password, since it's unique, but it always changes and has an expiration date. Then I thought, to left the password input empty and register user without it, but I think, that's not very secure. How should I do it?

Database structure for multiple authentication sources of users in a web app

I'm trying to work out how to structure a database schema that allows me to have multiple authentication sources for the same end-user.
For example, my web app would require users to sign in to utilize many of the functionality of features of the app. However, I do not want to be responsible for storing and authenticating user passwords.
I would like to outsource this responsibility to Google, Facebook, Twitter and similar identity providers.
So I would still need a database table of users, but no column for a password. However, these are authenticated would not be my concern. But I would still need to somehow associate my user with the identity providers user id. For example, if my user signs up with Google, I would store the users Google ID and associate this with my user. Meaning next time the user makes an attempt to login and is successfully authenticated at Google, I would make an attempt to find any user in my system that has this associated user id.
I've been trying to look for some common and recommended database structures, with no luck. Maybe I'm searching for the wrong terms for this because I cannot imagine that this is an uncommon way to do it. StackOverflow seems to do something similar.
The way I imagine it, it would allow me to associated multiple authentication sources for one app user. Meaning once I've signed up with Google, I can go to my settings and associate another account, for example, a Facebook account.
How should I go about achieving this in a flexible and clean way?
Thanks.
You need to know what data you have to save in your db to authenticate a user with a third party login.
For example, once I used Google to login users in my app, I save Google user id first time a user logs in and get data the next time.
You could have an entity with third party providers, so you will create a table with 2 values, user_id (your user data) and provider_id (Google, facebook, twitter...).
If you are going to use just one provider then you could add provider_id field to your users table.

Devise: Migrate Google Open ID to Google OAuth

Does anyone have clues about how to do this? I'm basically trying to replace the strategy for "Connect With Google" from OpenID to OAuth. The challenge is identifying an old user (user on Google open ID) when a user signs in under the new OAuth scheme.
I have a working implementation which relies on email address as the primary key, as the open ID strategy captures that. The problem is, I don't want to ask for email in the OAuth flow. The ideal value is simply Google user ID, but the Open ID strategy doesn't seem to capture that.
So I have open ID tokens like https://www.google.com/accounts/o8/id?id=AfSCwGQ4PUaidXSQddJugXKLqU5V0MrXFhJM6UHybPw and trying to understand if I could get a Google ID from that.
UPDATE: I explained here how I ended up doing this migration - http://softwareas.com/migrating-user-accounts-from-google-openid-to-google-oauth-to-google-plus
We don't have a strategy ready today that avoids the user seeing another approval page.
However, rather than attempt to do an OAuth1 based hybrid flow and have to add all that legacy code to your server, I'd suggest you simply correlate on email address and move to OAuth2 login. I'm assuming you're like the majority of sites that end up asking for email address because they usually want it for account recovery. Just make sure you get the email address from OpenId as one of the signed parameters.
Then use the userinfo.email scope and OAuth2 https://developers.google.com/accounts/docs/OAuth2Login and you should be able to migrate with less developer pain.
In addition, we're in the process of adding support for OpenIDConnect and it supports a parameter of login_hint so you'd add &login_hint=bob#gmail.com to your authorization URL and it will steer the approval to the right account. This is not documented right now but it may be useful for you to try it. The user's browser could be logged into Google with a number of accounts and you want to try to get the right one. Always check the email you get from the OAuth2 flow to make sure it matches since this is just a 'hint'.
Users will still have to re-authorize for OAuth2, but we have plans to skip this reauthorization in the future. The main point is to plan on using OAuth2 and we hope to deliver a seamless migration soon and you'll be on a supported protocol.
Google uses directed identifiers for OpenID that are unique per relying party and are explicitly designed to conceal any correlatable identifier for the user. So the short answer is, no there's no way to get a Google ID that corresponds with a given Google OpenID.
One option, however, might be to use Google's OpenID+OAuth Hybrid flow. This allows you to get an OAuth token as part of a normal OpenID flow, which could then be used to get the user's ID from the OAuth2 Login API, which you can then associate with their existing account. Once you've done that for all of your existing users, then switch to using the OAuth2 Login directly.
The trick, of course, with this approach is getting all of your users to login again so that you can send them through the new flow. That will come down to how long you're willing to wait to migrate accounts, and whether you're willing to prod existing users by emailing them and asking them to login again (similar to a forced password reset).

How to get unique token from OAuth2?

I am building a service in which users do not have to create an account to sign up, but use Google account as exactly does Stackoverflow.com
My Question is there is any unique information of an user in OAuth2 which never change, so I can use it as user id in my database.
After looking through Google OAuth2 API, I've ended up that all tokens are arbitrary every time session is established.
I would like to know how such sites as Stackoverflow extract the user information to sign up.
After getting the initial access token use the tokeninfo endpoint to get user_id.
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=" +
Uri.EscapeDataString(response.AccessToken))

Can email ID received from Google OpenID login be considered unique over time?

I am using Google OpenID for login to my website. I am using it through Tornado's built-in auth library. I retrieve email ID, first name, last name and name from the openID data. My question is can I use email ID retrieved in this way to remain unique over time - including its case? For e.g. Is it possible that a user may have email ID John.Doe#gmail.com today, but in future it may be john.doe#gmail.com? I cannot find any other field in the returned OpenID data that I can assume unique for a given user.
Update Maybe I should also add that I was hosting my website on Google App Engine before and was using its built-in login. When I migrated to Tornado based implementation, I used email ID from the old logins as the unique identifier of the users. In most of the cases that seems to have work, but recently I ran into a case where the user's email ID returned from OpenID was different from his email ID from GAE version only in case. Therefore I am trying to understand how this can happen.
Since it's an email address, you shouldn't consider case, as for normal email case is unimportant. So, you should be able to consider that unique in a case insensitive test.