Fabrizio Stellato
Fabrizio Stellato

Reputation: 1891

Google API -> Unable to obtain access token from JWT

I want to call Google API Analytics using Account service token generated from server.

I followed the guide on this link

This is my code for generating signed JSON Web Token:

    final GoogleCredential credential = GoogleCredential.fromStream(JWTSample.class.getResourceAsStream ("/account_secrets.json"))
            .createScoped(List.of(
                    "https://www.googleapis.com/auth/analytics",
                    "https://www.googleapis.com/auth/analytics.readonly")
            );
    final PrivateKey privateKey = credential.getServiceAccountPrivateKey();
    final String privateKeyId = credential.getServiceAccountPrivateKeyId();
    try {

        long now = System.currentTimeMillis();

        Algorithm algorithm = Algorithm.RSA256(null, (RSAPrivateKey) privateKey);
        String signedJwt = JWT.create()
                .withKeyId(privateKeyId)
                .withIssuer("[email protected]")
                .withAudience("https://oauth2.googleapis.com/token")
                .withIssuedAt(new Date(now))
                .withExpiresAt(new Date(now + 3600 * 1000L))
                .sign(algorithm);
        System.out.println(signedJwt);
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
}

The output is a signed JWT.

When I call Oauth2 service to generate access_token from signed JWT

 curl -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=<signed_JWT>' https://oauth2.googleapis.com/token

I receive this error:

{
    "error": "invalid_scope",
    "error_description": "Invalid oauth scope or ID token audience provided."
}

Any hints?

Upvotes: 1

Views: 3338

Answers (1)

matja
matja

Reputation: 4169

Decode the JWT assertion claim-set with echo "${SIGNED_JWT}" | cut -d. -f2 | base64 --decode and you'll see that there is no scope attribute.

The GoogleCredential instance has the scopes but they're not being passed to the JWT builder.

Add the scopes with this additional method after your JWT.create():

.withClaim("scope", credential.getServiceAccountScopesAsString())

Upvotes: 4

Related Questions