From 5a8f4676630854c53aa708a9c8b960770067f858 Mon Sep 17 00:00:00 2001 From: Timur Sadykov Date: Wed, 26 May 2021 14:29:01 -0700 Subject: [PATCH] feat: add Id token support for UserCredentials (#650) IdtokenProvider implementation for UserCredentials with unit tests for idtoken --- .gitignore | 3 + .../auth/oauth2/IdTokenCredentials.java | 7 +- .../google/auth/oauth2/UserCredentials.java | 71 ++++++++++++++----- .../auth/oauth2/MockTokenServerTransport.java | 14 ++-- .../auth/oauth2/UserCredentialsTest.java | 60 ++++++++++++++++ 5 files changed, 133 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index b637b4b46..fe226042f 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,6 @@ target/ # Intellij *.iml .idea/ + +# VS Code +.vscode/ \ No newline at end of file diff --git a/oauth2_http/java/com/google/auth/oauth2/IdTokenCredentials.java b/oauth2_http/java/com/google/auth/oauth2/IdTokenCredentials.java index 5629d4e81..be64a607b 100644 --- a/oauth2_http/java/com/google/auth/oauth2/IdTokenCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/IdTokenCredentials.java @@ -110,7 +110,12 @@ public class IdTokenCredentials extends OAuth2Credentials { private IdTokenCredentials(Builder builder) { this.idTokenProvider = Preconditions.checkNotNull(builder.getIdTokenProvider()); - this.targetAudience = Preconditions.checkNotNull(builder.getTargetAudience()); + + // target audience can't be used for UserCredentials + if (!(this.idTokenProvider instanceof UserCredentials)) { + this.targetAudience = Preconditions.checkNotNull(builder.getTargetAudience()); + } + this.options = builder.getOptions(); } diff --git a/oauth2_http/java/com/google/auth/oauth2/UserCredentials.java b/oauth2_http/java/com/google/auth/oauth2/UserCredentials.java index b8a05bcd1..780ec7538 100644 --- a/oauth2_http/java/com/google/auth/oauth2/UserCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/UserCredentials.java @@ -58,7 +58,8 @@ import java.util.Objects; /** OAuth2 Credentials representing a user's identity and consent. */ -public class UserCredentials extends GoogleCredentials implements QuotaProjectIdProvider { +public class UserCredentials extends GoogleCredentials + implements QuotaProjectIdProvider, IdTokenProvider { private static final String GRANT_TYPE = "refresh_token"; private static final String PARSE_ERROR_PREFIX = "Error parsing token refresh response. "; @@ -186,22 +187,7 @@ public static UserCredentials fromStream( /** Refreshes the OAuth2 access token by getting a new access token from the refresh token */ @Override public AccessToken refreshAccessToken() throws IOException { - if (refreshToken == null) { - throw new IllegalStateException( - "UserCredentials instance cannot refresh because there is no" + " refresh token."); - } - GenericData tokenRequest = new GenericData(); - tokenRequest.set("client_id", clientId); - tokenRequest.set("client_secret", clientSecret); - tokenRequest.set("refresh_token", refreshToken); - tokenRequest.set("grant_type", GRANT_TYPE); - UrlEncodedContent content = new UrlEncodedContent(tokenRequest); - - HttpRequestFactory requestFactory = transportFactory.create().createRequestFactory(); - HttpRequest request = requestFactory.buildPostRequest(new GenericUrl(tokenServerUri), content); - request.setParser(new JsonObjectParser(JSON_FACTORY)); - HttpResponse response = request.execute(); - GenericData responseData = response.parseAs(GenericData.class); + GenericData responseData = doRefreshAccessToken(); String accessToken = OAuth2Utils.validateString(responseData, "access_token", PARSE_ERROR_PREFIX); int expiresInSeconds = @@ -210,6 +196,33 @@ public AccessToken refreshAccessToken() throws IOException { return new AccessToken(accessToken, new Date(expiresAtMilliseconds)); } + /** + * Returns a Google ID Token from the refresh token response. + * + * @param targetAudience This can't be used for UserCredentials. + * @param options list of Credential specific options for the token. Currently unused for + * UserCredentials. + * @throws IOException if the attempt to get an IdToken failed + * @return IdToken object which includes the raw id_token, expiration and audience + */ + @Override + public IdToken idTokenWithAudience(String targetAudience, List