Google and OAuth 2.0 Compatibility (Eliminate all other factors, and the one which remains must be the truth. (Sherlock Holmes))

Over the weekend I was pinged by my QA engineers about new failures in our OAuth 2.0 test suite.
Not a good sign, just a few days before the OpenIG 3.1 release date ! Anyway, I’ve made my hands
dirty to track down the problem up to the source. Here is the story :)

Everything starts with …

… a failure, at least I had the screenshot of a nice Exception, pretty explicit by the way:

The failure

… then you start digging

… on your side. Yeah, you must have done something wrong in your code, Google is
just working (Apple ©), right ?

The part of the code referred by that stack trace is dealing with the Access Token
Response JSON structure returned from the OAuth 2.0 Token endpoint. But this has not
been changed since it was first checked in (or almost, nothing recent at least), and the
QA tests that were failing on friday have been working previously.

I’ve tried to think about every code checkin’ to see the potential impact on the
expected behaviour, found nothing.

On the QA side, they re-run an older OpenIG’s version (that was working, remember ?), and now it’s failing too !?


… looking more closely to what Google send

At that point, it’s time to open your IDE and debug OpenIG, this way we’ll see what see OpenIG see…

No wonder, it’s really receiving a successful access token response of the following form:

  "access_token": "ya29.1gD56tBWtHW3K7oZ0FINTnsqa4VYiE2YGZeQXgJ4ID79E-mZxNWoyYi7pKrs_Vyxj8FZbuxh_RGTJw",
  "token_type": "Bearer",
  "expires_in": "3600",
  "refresh_token": "1/dGjGYC7sDFaBwpdUVpkJP2mYFYTU8HAh7T6szsKGYTs"

expires_in is really a String, even if semantically it’s a Number !

Ok Google is now sending a String instead of a Number for this attribute.

My world collapse: Google can’t be wrong for something that simple !

That reminds me a famous Sherlock Holmes quote: Eliminate all other factors, and the one which remains must be the truth.


… what about the spec ?

As per the OAuth 2.0 Spec, a successful response looks like the following:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

They even give a syntax for
expires_in attribute:

expires-in = 1*DIGIT

Pretty simple, though ?

… let’s find a solution

Hopefully, it was not very hard to fix: I just made one of our class a little bit smarter
(dealing especially with the String case).

Tested and committed, ready for the release :)

… wait a minute, what changed on Google’s side ?

They seem to have updated their OAuth 2.0 service implementation.

Take a look at the OpenID Connect Discovery endpoint returned JSON:

  "issuer": "",
  "authorization_endpoint": "",
  "token_endpoint": "",
  "userinfo_endpoint": "",
  "revocation_endpoint": "",
  "jwks_uri": "",
  "response_types_supported": [
    "code", "token", "id_token",
    "code token", "code id_token", "token id_token", "code token id_token",
  "subject_types_supported": [ "public" ],
  "id_token_alg_values_supported": [ "RS256" ]

And, more closely to the token_endpoint value: it’s using a v3 API.
It’s not even advertised on the Google API Explorer (yet ?).

Another hint that something changed was in the last edited timestamp at the bottom
of the OpenIDConnect and OAuth2WebServer google developers pages:

Edited on Friday the 5th

Funny facts

I played with Google OAuth Playground this morning (BTW, it’s pretty neat and usable, good stuff).

Surprisingly, when you choose the Google OAuth endpoints set, you’ll see they’re not
using the v3 one yet: they’re using

When manually re-configured to use the v3 API, you clearly see the String:

Configured with v3 endpoints


©2022 ForgeRock - we provide an identity and access platform to secure every online relationship for the enterprise market, educational sector and even entire countries. Click to view our privacy policy and terms of use.

Log in with your credentials

Forgot your details?