Eric G
Eric G

Reputation: 1292

How to use google python oauth libraries to implement OpenID Connect?

I am evaluating different options for authentication in a python App Engine flex environment, for apps that run within a G Suite domain.

I am trying to put together the OpenID Connect "Server flow" instructions here with how google-auth-library-python implements the general OAuth2 instructions here.

I kind of follow things up until 4. Exchange code for access token and ID token, which looks like flow.fetch_token, except it says "response to this request contains the following fields in a JSON array," and it includes not just the access token but the id token and other things. I did see this patch to the library. Does that mean I could use some flow.fetch_token to create an IDTokenCredentials (how?) and then use this to build an OpenID Connect API client (and where is that API documented)? And what about validating the id token, is there a separate python library to help with that or is that part of the API library?

It is all very confusing. A great deal would be cleared up with some actual "soup to nuts" example code but I haven't found anything anywhere on the internet, which makes me think (a) perhaps this is not a viable way to do authentication, or (b) it is so recent the python libraries have not caught up? I would however much rather do authentication on the server than in the client with Google Sign-In.

Any suggestions or links to code are much appreciated.

Upvotes: 2

Views: 2113

Answers (2)

Eric G
Eric G

Reputation: 1292

OK, I think I found my answer in the source code now.

google.oauth2.credentials.Credentials exposes id_token:

Depending on the authorization server and the scopes requested, this may be populated when credentials are obtained and updated when refresh is called. This token is a JWT. It can be verified and decoded [as @kavindu-dodanduwa pointed out] using google.oauth2.id_token.verify_oauth2_token.

And several layers down the call stack we can see fetch_token does some minimal validation of the response JSON (checking that an access token was returned, etc.) but basically passes through whatever it gets from the token endpoint, including (i.e. if an OpenID Connect scope is included) the id token as a JWT.

EDIT:

And the final piece of the puzzle is the translation of tokens from the (generic) OAuthSession to (Google-specific) credentials in google_auth_oauthlib.helpers, where the id_token is grabbed, if it exists.

Note that the generic oauthlib library does seem to implement OpenID Connect now, but looks to be very recent and in process (July 2018). Google doesn't seem to use any of this at the moment (this threw me off a bit).

Upvotes: 1

Kavindu Dodanduwa
Kavindu Dodanduwa

Reputation: 13077

It seems Google's python library contains a module for id token validation. This can be found at google.oauth2.id_token module. Once validated, it will return the decoded token which you can use to obtain user information.

from google.oauth2 import id_token
from google.auth.transport import requests

request = requests.Request()

id_info = id_token.verify_oauth2_token(
    token, request, 'my-client-id.example.com')

if id_info['iss'] != 'https://accounts.google.com':
    raise ValueError('Wrong issuer.')

userid = id_info['sub']

Once you obtain user information, you should follow authentication process as described in Authenticate the user section.

Upvotes: 2

Related Questions