Question

I've got a valid OAuth2 token that Google accepts, but GoogleIdTokenVerifier cannot even parse it.

The token is ya29.1.AADtN_XcjzHgauKetBvrbgHImGFg1pjiHRQAKHyTglBDjEZsTPUMQJ5p-xAKtk955_4r6MdnTe3HZ08 (no worries, it's already expired).

It's obtained on Android using

accountManager.blockingGetAuthToken(account, "oauth2:https://www.googleapis.com/auth/userinfo.email", true);

When I call https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=... I get sane result like

{
  "issued_to": "34951113407.apps.googleusercontent.com",
  "audience": "34951113407.apps.googleusercontent.com",
  "scope": "https://www.googleapis.com/auth/userinfo.email",
  "expires_in": 3175,
  "email": "me@gmail.com",
  "verified_email": true,
  "access_type": "offline"
}

So it must be a valid token. But when I call

new GoogleIdTokenVerifier(new UrlFetchTransport(), JacksonFactory.getDefaultInstance())
    .verify(authToken)

It gives me

com.fasterxml.jackson.core.JsonParseException: Unexpected character ('É' (code 201)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
 at [Source: java.io.ByteArrayInputStream@69886979; line: 1, column: 2]
    at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1378)
    at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:599)
    at com.fasterxml.jackson.core.base.ParserMinimalBase._reportUnexpectedChar(ParserMinimalBase.java:520)
    at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._handleUnexpectedValue(UTF8StreamJsonParser.java:2275)
    at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._nextTokenNotInObject(UTF8StreamJsonParser.java:788)
    at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.nextToken(UTF8StreamJsonParser.java:674)
    at com.google.api.client.json.jackson2.JacksonParser.nextToken(JacksonParser.java:55)
    at com.google.api.client.json.JsonParser.startParsing(JsonParser.java:213)
    at com.google.api.client.json.JsonParser.parse(JsonParser.java:372)
    at com.google.api.client.json.JsonParser.parse(JsonParser.java:328)
    at com.google.api.client.json.JsonParser.parseAndClose(JsonParser.java:158)
    at com.google.api.client.json.JsonParser.parseAndClose(JsonParser.java:140)
    at com.google.api.client.json.JsonFactory.fromInputStream(JsonFactory.java:206)
    at com.google.api.client.json.webtoken.JsonWebSignature$Parser.parse(JsonWebSignature.java:480)
    at com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.parse(GoogleIdToken.java:57)
    at com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier.verify(GoogleIdTokenVerifier.java:190)

By debugging JsonWebSignature it seems that token payload is just 1.

  • Android 4.4.2
  • com.google.http-client:google-http-client-jackson2:1.17.0-rc
  • com.fasterxml.jackson.core:jackson-core:2.3.0 (also tried included 2.1.3 from transient dependencies of google-http-client-jackson) Also tried GsonFactory, exception is different, but also clearly cannot be parsed by JsonWebSignature.parse().

What I did wrong? Are there different tokens formats out there?

Was it helpful?

Solution

There are indeed different token formats out there.

The OAuth2 token you have there is the access_token -- it says that your software is authorized with the scope you requested, but it doesn't say anything about which user is actually making the request.

There is another type of token which the GoogleIdTokenVerifier expects to verify: an OpenID Connect id_token. A lot of services use that one, because it means some third party is authenticating that the traffic you're looking at came from that human (more or less!).

There's a little more background here, but the short version is that you should consider using [GoogleAuthUtil#getToken(android.content.Context, java.lang.String, java.lang.String)](https://developers.google.com/android/reference/com/google/android/gms/auth/GoogleAuthUtil#getToken(android.content.Context, java.lang.String, java.lang.String)) -- it will return the id_token as a String -- or else consider exactly which scopes you need, and consider requesting the openid scope instead of the current oauth2:https://www.googleapis.com/auth/userinfo.email.

I know this answer is probably too late to help you :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top