From 98502751b7a966b07b81d0fd4124d674ee89bf3d Mon Sep 17 00:00:00 2001 From: Sijun Liu Date: Sat, 11 Feb 2023 18:07:43 -0800 Subject: [PATCH 1/2] fix: create and reuse self signed jwt creds for better performance --- .../auth/oauth2/ServiceAccountCredentials.java | 17 +++++++++++++++-- .../oauth2/ServiceAccountCredentialsTest.java | 2 ++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java index 479041ead..3109f68c8 100644 --- a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java @@ -110,6 +110,8 @@ public class ServiceAccountCredentials extends GoogleCredentials private transient HttpTransportFactory transportFactory; + private transient JwtCredentials selfSignedJwtCredentialsWithScope = null; + /** * Internal constructor * @@ -143,6 +145,12 @@ public class ServiceAccountCredentials extends GoogleCredentials this.lifetime = builder.lifetime; this.useJwtAccessWithScope = builder.useJwtAccessWithScope; this.defaultRetriesEnabled = builder.defaultRetriesEnabled; + + // Create a jwt credential for self signed jwt with scopes, and reuse it to improve the + // performance. For example see https://github.com/googleapis/google-cloud-java/issues/3149. + if (!createScopedRequired() && this.useJwtAccessWithScope) { + this.selfSignedJwtCredentialsWithScope = createSelfSignedJwtCredentials(null); + } } /** @@ -704,6 +712,11 @@ public boolean getUseJwtAccessWithScope() { return useJwtAccessWithScope; } + @VisibleForTesting + JwtCredentials getSelfSignedJwtCredentialsWithScope() { + return selfSignedJwtCredentialsWithScope; + } + @Override public String getAccount() { return getClientEmail(); @@ -935,8 +948,8 @@ public Map> getRequestMetadata(URI uri) throws IOException // Otherwise, use self signed JWT with uri as the audience. JwtCredentials jwtCredentials; if (!createScopedRequired() && useJwtAccessWithScope) { - // Create JWT credentials with the scopes. - jwtCredentials = createSelfSignedJwtCredentials(null); + // Reuse selfSignedJwtCredentialsWithScope to improve the performance. + jwtCredentials = selfSignedJwtCredentialsWithScope; } else { // Create JWT credentials with the uri as audience. jwtCredentials = createSelfSignedJwtCredentials(uri); diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java index 14eb16b92..f3b3f0983 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java @@ -1465,6 +1465,7 @@ public void getRequestMetadata_selfSignedJWT_withScopes() throws IOException { .build(); Map> metadata = credentials.getRequestMetadata(CALL_URI); + assertNotNull(((ServiceAccountCredentials) credentials).getSelfSignedJwtCredentialsWithScope()); verifyJwtAccess(metadata, "dummy.scope"); } @@ -1518,6 +1519,7 @@ public void getRequestMetadata_selfSignedJWT_withAudience() throws IOException { .build(); Map> metadata = credentials.getRequestMetadata(CALL_URI); + assertNull(((ServiceAccountCredentials) credentials).getSelfSignedJwtCredentialsWithScope()); verifyJwtAccess(metadata, null); } From 5753eca1a68ad5fdef8ed4260451e3c25160d76c Mon Sep 17 00:00:00 2001 From: Sijun Liu Date: Mon, 13 Feb 2023 18:00:05 -0800 Subject: [PATCH 2/2] only create jwt cred when needed --- .../google/auth/oauth2/ServiceAccountCredentials.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java index 3109f68c8..c6c95a71c 100644 --- a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java @@ -145,12 +145,6 @@ public class ServiceAccountCredentials extends GoogleCredentials this.lifetime = builder.lifetime; this.useJwtAccessWithScope = builder.useJwtAccessWithScope; this.defaultRetriesEnabled = builder.defaultRetriesEnabled; - - // Create a jwt credential for self signed jwt with scopes, and reuse it to improve the - // performance. For example see https://github.com/googleapis/google-cloud-java/issues/3149. - if (!createScopedRequired() && this.useJwtAccessWithScope) { - this.selfSignedJwtCredentialsWithScope = createSelfSignedJwtCredentials(null); - } } /** @@ -948,7 +942,10 @@ public Map> getRequestMetadata(URI uri) throws IOException // Otherwise, use self signed JWT with uri as the audience. JwtCredentials jwtCredentials; if (!createScopedRequired() && useJwtAccessWithScope) { - // Reuse selfSignedJwtCredentialsWithScope to improve the performance. + // Create selfSignedJwtCredentialsWithScope when needed and reuse it for better performance. + if (selfSignedJwtCredentialsWithScope == null) { + selfSignedJwtCredentialsWithScope = createSelfSignedJwtCredentials(null); + } jwtCredentials = selfSignedJwtCredentialsWithScope; } else { // Create JWT credentials with the uri as audience.