From f4980c77566bbd5ef4c532acb199d7d484dbcd01 Mon Sep 17 00:00:00 2001 From: arithmetic1728 <58957152+arithmetic1728@users.noreply.github.com> Date: Tue, 13 Jul 2021 22:20:06 -0700 Subject: [PATCH] feat: allow scopes for self signed jwt (#689) * feat: self signed jwt support * update * address comments * allow to use uri as audience * address comments --- .../com/google/auth/oauth2/JwtClaims.java | 4 +- .../oauth2/ServiceAccountCredentials.java | 143 ++++++++++++++---- .../ServiceAccountJwtAccessCredentials.java | 21 +-- .../com/google/auth/oauth2/JwtClaimsTest.java | 12 ++ .../oauth2/ServiceAccountCredentialsTest.java | 114 +++++++++++--- ...erviceAccountJwtAccessCredentialsTest.java | 30 +--- 6 files changed, 230 insertions(+), 94 deletions(-) diff --git a/oauth2_http/java/com/google/auth/oauth2/JwtClaims.java b/oauth2_http/java/com/google/auth/oauth2/JwtClaims.java index 83ee0a0a0..5e36ebde1 100644 --- a/oauth2_http/java/com/google/auth/oauth2/JwtClaims.java +++ b/oauth2_http/java/com/google/auth/oauth2/JwtClaims.java @@ -106,7 +106,9 @@ public JwtClaims merge(JwtClaims other) { * @return true if all required fields have been set; false otherwise */ public boolean isComplete() { - return getAudience() != null && getIssuer() != null && getSubject() != null; + boolean hasScopes = + getAdditionalClaims().containsKey("scope") && !getAdditionalClaims().get("scope").isEmpty(); + return (getAudience() != null || hasScopes) && getIssuer() != null && getSubject() != null; } @AutoValue.Builder diff --git a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java index 377b4dbf1..27d67f809 100644 --- a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java @@ -77,6 +77,7 @@ import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Collection; +import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; @@ -109,9 +110,9 @@ public class ServiceAccountCredentials extends GoogleCredentials private final Collection defaultScopes; private final String quotaProjectId; private final int lifetime; + private final boolean useJwtAccessWithScope; private transient HttpTransportFactory transportFactory; - private transient ServiceAccountJwtAccessCredentials jwtCredentials = null; /** * Constructor with minimum identifying information and custom HTTP transport. @@ -133,6 +134,7 @@ public class ServiceAccountCredentials extends GoogleCredentials * most 43200 (12 hours). If the token is used for calling a Google API, then the value should * be at most 3600 (1 hour). If the given value is 0, then the default value 3600 will be used * when creating the credentials. + * @param useJwtAccessWithScope whether self signed JWT with scopes should be always used. */ ServiceAccountCredentials( String clientId, @@ -146,7 +148,8 @@ public class ServiceAccountCredentials extends GoogleCredentials String serviceAccountUser, String projectId, String quotaProjectId, - int lifetime) { + int lifetime, + boolean useJwtAccessWithScope) { this.clientId = clientId; this.clientEmail = Preconditions.checkNotNull(clientEmail); this.privateKey = Preconditions.checkNotNull(privateKey); @@ -167,18 +170,7 @@ public class ServiceAccountCredentials extends GoogleCredentials throw new IllegalStateException("lifetime must be less than or equal to 43200"); } this.lifetime = lifetime; - - // Use self signed JWT if scopes is not set, see https://google.aip.dev/auth/4111. - if (this.scopes.isEmpty()) { - jwtCredentials = - new ServiceAccountJwtAccessCredentials.Builder() - .setClientEmail(clientEmail) - .setClientId(clientId) - .setPrivateKey(privateKey) - .setPrivateKeyId(privateKeyId) - .setQuotaProjectId(quotaProjectId) - .build(); - } + this.useJwtAccessWithScope = useJwtAccessWithScope; } /** @@ -492,7 +484,8 @@ static ServiceAccountCredentials fromPkcs8( serviceAccountUser, projectId, quotaProject, - DEFAULT_LIFETIME_IN_SECONDS); + DEFAULT_LIFETIME_IN_SECONDS, + false); } /** Helper to convert from a PKCS#8 String to an RSA private key */ @@ -698,7 +691,8 @@ public GoogleCredentials createScoped( serviceAccountUser, projectId, quotaProjectId, - lifetime); + lifetime, + useJwtAccessWithScope); } /** @@ -714,6 +708,16 @@ public ServiceAccountCredentials createWithCustomLifetime(int lifetime) { return this.toBuilder().setLifetime(lifetime).build(); } + /** + * Clones the service account with a new useJwtAccessWithScope value. + * + * @param useJwtAccessWithScope whether self signed JWT with scopes should be used + * @return the cloned service account credentials with the given useJwtAccessWithScope + */ + public ServiceAccountCredentials createWithUseJwtAccessWithScope(boolean useJwtAccessWithScope) { + return this.toBuilder().setUseJwtAccessWithScope(useJwtAccessWithScope).build(); + } + @Override public GoogleCredentials createDelegated(String user) { return new ServiceAccountCredentials( @@ -728,7 +732,8 @@ public GoogleCredentials createDelegated(String user) { user, projectId, quotaProjectId, - lifetime); + lifetime, + useJwtAccessWithScope); } public final String getClientId() { @@ -776,6 +781,10 @@ int getLifetime() { return lifetime; } + public boolean getUseJwtAccessWithScope() { + return useJwtAccessWithScope; + } + @Override public String getAccount() { return getClientEmail(); @@ -833,7 +842,8 @@ public int hashCode() { scopes, defaultScopes, quotaProjectId, - lifetime); + lifetime, + useJwtAccessWithScope); } @Override @@ -849,6 +859,7 @@ public String toString() { .add("serviceAccountUser", serviceAccountUser) .add("quotaProjectId", quotaProjectId) .add("lifetime", lifetime) + .add("useJwtAccessWithScope", useJwtAccessWithScope) .toString(); } @@ -867,7 +878,8 @@ public boolean equals(Object obj) { && Objects.equals(this.scopes, other.scopes) && Objects.equals(this.defaultScopes, other.defaultScopes) && Objects.equals(this.quotaProjectId, other.quotaProjectId) - && Objects.equals(this.lifetime, other.lifetime); + && Objects.equals(this.lifetime, other.lifetime) + && Objects.equals(this.useJwtAccessWithScope, other.useJwtAccessWithScope); } String createAssertion(JsonFactory jsonFactory, long currentTime, String audience) @@ -937,11 +949,58 @@ String createAssertionForIdToken( } } + /** + * Self signed JWT uses uri as audience, which should have the "https://{host}/" format. For + * instance, if the uri is "https://compute.googleapis.com/compute/v1/projects/", then this + * function returns "https://compute.googleapis.com/". + */ + @VisibleForTesting + static URI getUriForSelfSignedJWT(URI uri) { + if (uri == null || uri.getScheme() == null || uri.getHost() == null) { + return uri; + } + try { + return new URI(uri.getScheme(), uri.getHost(), "/", null); + } catch (URISyntaxException unused) { + return uri; + } + } + + @VisibleForTesting + JwtCredentials createSelfSignedJwtCredentials(final URI uri) { + // Create a JwtCredentials for self signed JWT. See https://google.aip.dev/auth/4111. + JwtClaims.Builder claimsBuilder = + JwtClaims.newBuilder().setIssuer(clientEmail).setSubject(clientEmail); + + if (uri == null) { + // If uri is null, use scopes. + String scopeClaim = ""; + if (!scopes.isEmpty()) { + scopeClaim = Joiner.on(' ').join(scopes); + } else { + scopeClaim = Joiner.on(' ').join(defaultScopes); + } + claimsBuilder.setAdditionalClaims(Collections.singletonMap("scope", scopeClaim)); + } else { + // otherwise, use audience with the uri. + claimsBuilder.setAudience(getUriForSelfSignedJWT(uri).toString()); + } + return JwtCredentials.newBuilder() + .setPrivateKey(privateKey) + .setPrivateKeyId(privateKeyId) + .setJwtClaims(claimsBuilder.build()) + .setClock(clock) + .build(); + } + @Override public void getRequestMetadata( final URI uri, Executor executor, final RequestMetadataCallback callback) { - if (jwtCredentials != null && uri != null) { - jwtCredentials.getRequestMetadata(uri, executor, callback); + if (useJwtAccessWithScope) { + // This will call getRequestMetadata(URI uri), which handles self signed JWT logic. + // Self signed JWT doesn't use network, so here we do a blocking call to improve + // efficiency. executor will be ignored since it is intended for async operation. + blockingGetToCallback(uri, callback); } else { super.getRequestMetadata(uri, executor, callback); } @@ -950,17 +1009,31 @@ public void getRequestMetadata( /** Provide the request metadata by putting an access JWT directly in the metadata. */ @Override public Map> getRequestMetadata(URI uri) throws IOException { - if (scopes.isEmpty() && defaultScopes.isEmpty() && uri == null) { + if (createScopedRequired() && uri == null) { throw new IOException( - "Scopes and uri are not configured for service account. Either pass uri" - + " to getRequestMetadata to use self signed JWT, or specify the scopes" - + " by calling createScoped or passing scopes to constructor."); + "Scopes and uri are not configured for service account. Specify the scopes" + + " by calling createScoped or passing scopes to constructor or" + + " providing uri to getRequestMetadata."); } - if (jwtCredentials != null && uri != null) { - return jwtCredentials.getRequestMetadata(uri); - } else { + + // If scopes are provided but we cannot use self signed JWT, then use scopes to get access + // token. + if (!createScopedRequired() && !useJwtAccessWithScope) { return super.getRequestMetadata(uri); } + + // If scopes are provided and self signed JWT can be used, use self signed JWT with scopes. + // Otherwise, use self signed JWT with uri as the audience. + JwtCredentials jwtCredentials; + if (!createScopedRequired() && useJwtAccessWithScope) { + // Create JWT credentials with the scopes. + jwtCredentials = createSelfSignedJwtCredentials(null); + } else { + // Create JWT credentials with the uri as audience. + jwtCredentials = createSelfSignedJwtCredentials(uri); + } + Map> requestMetadata = jwtCredentials.getRequestMetadata(null); + return addQuotaProjectIdToRequestMetadata(quotaProjectId, requestMetadata); } @SuppressWarnings("unused") @@ -997,6 +1070,7 @@ public static class Builder extends GoogleCredentials.Builder { private HttpTransportFactory transportFactory; private String quotaProjectId; private int lifetime = DEFAULT_LIFETIME_IN_SECONDS; + private boolean useJwtAccessWithScope = false; protected Builder() {} @@ -1013,6 +1087,7 @@ protected Builder(ServiceAccountCredentials credentials) { this.projectId = credentials.projectId; this.quotaProjectId = credentials.quotaProjectId; this.lifetime = credentials.lifetime; + this.useJwtAccessWithScope = credentials.useJwtAccessWithScope; } public Builder setClientId(String clientId) { @@ -1077,6 +1152,11 @@ public Builder setLifetime(int lifetime) { return this; } + public Builder setUseJwtAccessWithScope(boolean useJwtAccessWithScope) { + this.useJwtAccessWithScope = useJwtAccessWithScope; + return this; + } + public String getClientId() { return clientId; } @@ -1125,6 +1205,10 @@ public int getLifetime() { return lifetime; } + public boolean getUseJwtAccessWithScope() { + return useJwtAccessWithScope; + } + public ServiceAccountCredentials build() { return new ServiceAccountCredentials( clientId, @@ -1138,7 +1222,8 @@ public ServiceAccountCredentials build() { serviceAccountUser, projectId, quotaProjectId, - lifetime); + lifetime, + useJwtAccessWithScope); } } } diff --git a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java index 2380b1cf6..707b657a7 100644 --- a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java @@ -54,7 +54,6 @@ import java.io.InputStream; import java.io.ObjectInputStream; import java.net.URI; -import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; @@ -332,35 +331,17 @@ public boolean hasRequestMetadataOnly() { return true; } - /** - * Self signed JWT uses uri as audience, which should have the "https://{host}/" format. For - * instance, if the uri is "https://compute.googleapis.com/compute/v1/projects/", then this - * function returns "https://compute.googleapis.com/". - */ - @VisibleForTesting - static URI getUriForSelfSignedJWT(URI uri) { - if (uri == null || uri.getScheme() == null || uri.getHost() == null) { - return uri; - } - try { - return new URI(uri.getScheme(), uri.getHost(), "/", null); - } catch (URISyntaxException unused) { - return uri; - } - } - @Override public void getRequestMetadata( final URI uri, Executor executor, final RequestMetadataCallback callback) { // It doesn't use network. Only some CPU work on par with TLS handshake. So it's preferrable // to do it in the current thread, which is likely to be the network thread. - blockingGetToCallback(getUriForSelfSignedJWT(uri), callback); + blockingGetToCallback(uri, callback); } /** Provide the request metadata by putting an access JWT directly in the metadata. */ @Override public Map> getRequestMetadata(URI uri) throws IOException { - uri = getUriForSelfSignedJWT(uri); if (uri == null) { if (defaultAudience != null) { uri = defaultAudience; diff --git a/oauth2_http/javatests/com/google/auth/oauth2/JwtClaimsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/JwtClaimsTest.java index b67f110de..a54f87e65 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/JwtClaimsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/JwtClaimsTest.java @@ -136,4 +136,16 @@ public void testMergeAdditionalClaims() { assertEquals("bar", mergedAdditionalClaims.get("foo")); assertEquals("qwer", mergedAdditionalClaims.get("asdf")); } + + @Test + public void testIsComplete() { + // Test JwtClaim is complete if audience is not set but scope is provided. + JwtClaims claims = + JwtClaims.newBuilder() + .setIssuer("issuer-1") + .setSubject("subject-1") + .setAdditionalClaims(Collections.singletonMap("scope", "foo")) + .build(); + assertTrue(claims.isComplete()); + } } diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java index 3fc903d73..803d4fc8f 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java @@ -420,20 +420,15 @@ public void createdScoped_enablesAccessTokens() throws IOException { try { credentials.getRequestMetadata(null); - fail("Should not be able to get token without scopes, defaultScopes and uri"); + fail("Should not be able to get token without scopes"); } catch (IOException e) { assertTrue( "expected to fail with exception", e.getMessage().contains("Scopes and uri are not configured for service account")); } - // Since scopes are not provided, self signed JWT will be used. - Map> metadata = credentials.getRequestMetadata(CALL_URI); - verifyJwtAccess(metadata); - - // Since scopes are provided, self signed JWT will not be used. GoogleCredentials scopedCredentials = credentials.createScoped(SCOPES); - metadata = scopedCredentials.getRequestMetadata(CALL_URI); + Map> metadata = scopedCredentials.getRequestMetadata(CALL_URI); TestUtils.assertContainsBearerToken(metadata, ACCESS_TOKEN); } @@ -1074,7 +1069,7 @@ public void toString_containsFields() throws IOException { String.format( "ServiceAccountCredentials{clientId=%s, clientEmail=%s, privateKeyId=%s, " + "transportFactoryClassName=%s, tokenServerUri=%s, scopes=%s, defaultScopes=%s, serviceAccountUser=%s, " - + "quotaProjectId=%s, lifetime=3600}", + + "quotaProjectId=%s, lifetime=3600, useJwtAccessWithScope=false}", CLIENT_ID, CLIENT_EMAIL, PRIVATE_KEY_ID, @@ -1236,6 +1231,29 @@ public void fromStream_noPrivateKeyId_throws() throws IOException { testFromStreamException(serviceAccountStream, "private_key_id"); } + @Test + public void getUriForSelfSignedJWT() { + assertNull(ServiceAccountCredentials.getUriForSelfSignedJWT(null)); + + URI uri = URI.create("https://compute.googleapis.com/compute/v1/projects/"); + URI expected = URI.create("https://compute.googleapis.com/"); + assertEquals(expected, ServiceAccountCredentials.getUriForSelfSignedJWT(uri)); + } + + @Test + public void getUriForSelfSignedJWT_noHost() { + URI uri = URI.create("file:foo"); + URI expected = URI.create("file:foo"); + assertEquals(expected, ServiceAccountCredentials.getUriForSelfSignedJWT(uri)); + } + + @Test + public void getUriForSelfSignedJWT_forStaticAudience_returnsURI() { + URI uri = URI.create("compute.googleapis.com"); + URI expected = URI.create("compute.googleapis.com"); + assertEquals(expected, ServiceAccountCredentials.getUriForSelfSignedJWT(uri)); + } + @Test public void getRequestMetadataSetsQuotaProjectId() throws IOException { MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); @@ -1328,11 +1346,65 @@ public void onFailure(Throwable exception) { } @Test - public void getRequestMetadataWithCallback_selfSignedJWT() throws IOException { - MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); - transportFactory.transport.addClient(CLIENT_ID, "unused-client-secret"); - transportFactory.transport.addServiceAccount(CLIENT_EMAIL, ACCESS_TOKEN); + public void getRequestMetadata_selfSignedJWT_withScopes() throws IOException { + PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(PRIVATE_KEY_PKCS8); + GoogleCredentials credentials = + ServiceAccountCredentials.newBuilder() + .setClientId(CLIENT_ID) + .setClientEmail(CLIENT_EMAIL) + .setPrivateKey(privateKey) + .setPrivateKeyId(PRIVATE_KEY_ID) + .setScopes(SCOPES) + .setServiceAccountUser(USER) + .setProjectId(PROJECT_ID) + .setHttpTransportFactory(new MockTokenServerTransportFactory()) + .setUseJwtAccessWithScope(true) + .build(); + + Map> metadata = credentials.getRequestMetadata(CALL_URI); + verifyJwtAccess(metadata, "dummy.scope"); + } + @Test + public void getRequestMetadata_selfSignedJWT_withAudience() throws IOException { + PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(PRIVATE_KEY_PKCS8); + GoogleCredentials credentials = + ServiceAccountCredentials.newBuilder() + .setClientId(CLIENT_ID) + .setClientEmail(CLIENT_EMAIL) + .setPrivateKey(privateKey) + .setPrivateKeyId(PRIVATE_KEY_ID) + .setServiceAccountUser(USER) + .setProjectId(PROJECT_ID) + .setHttpTransportFactory(new MockTokenServerTransportFactory()) + .build(); + + Map> metadata = credentials.getRequestMetadata(CALL_URI); + verifyJwtAccess(metadata, null); + } + + @Test + public void getRequestMetadata_selfSignedJWT_withDefaultScopes() throws IOException { + PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(PRIVATE_KEY_PKCS8); + GoogleCredentials credentials = + ServiceAccountCredentials.newBuilder() + .setClientId(CLIENT_ID) + .setClientEmail(CLIENT_EMAIL) + .setPrivateKey(privateKey) + .setPrivateKeyId(PRIVATE_KEY_ID) + .setScopes(null, SCOPES) + .setServiceAccountUser(USER) + .setProjectId(PROJECT_ID) + .setHttpTransportFactory(new MockTokenServerTransportFactory()) + .setUseJwtAccessWithScope(true) + .build(); + + Map> metadata = credentials.getRequestMetadata(null); + verifyJwtAccess(metadata, "dummy.scope"); + } + + @Test + public void getRequestMetadataWithCallback_selfSignedJWT() throws IOException { PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(PRIVATE_KEY_PKCS8); GoogleCredentials credentials = ServiceAccountCredentials.newBuilder() @@ -1340,11 +1412,12 @@ public void getRequestMetadataWithCallback_selfSignedJWT() throws IOException { .setClientEmail(CLIENT_EMAIL) .setPrivateKey(privateKey) .setPrivateKeyId(PRIVATE_KEY_ID) - .setScopes(null, DEFAULT_SCOPES) .setServiceAccountUser(USER) .setProjectId(PROJECT_ID) .setQuotaProjectId("my-quota-project-id") - .setHttpTransportFactory(transportFactory) + .setHttpTransportFactory(new MockTokenServerTransportFactory()) + .setUseJwtAccessWithScope(true) + .setScopes(SCOPES) .build(); final AtomicBoolean success = new AtomicBoolean(false); @@ -1355,7 +1428,7 @@ public void getRequestMetadataWithCallback_selfSignedJWT() throws IOException { @Override public void onSuccess(Map> metadata) { try { - verifyJwtAccess(metadata); + verifyJwtAccess(metadata, "dummy.scope"); } catch (IOException e) { fail("Should not throw a failure"); } @@ -1371,7 +1444,8 @@ public void onFailure(Throwable exception) { assertTrue("Should have run onSuccess() callback", success.get()); } - private void verifyJwtAccess(Map> metadata) throws IOException { + private void verifyJwtAccess(Map> metadata, String expectedScopeClaim) + throws IOException { assertNotNull(metadata); List authorizations = metadata.get(AuthHttpConstants.AUTHORIZATION); assertNotNull("Authorization headers not found", authorizations); @@ -1387,7 +1461,13 @@ private void verifyJwtAccess(Map> metadata) throws IOExcept JsonWebSignature.parse(GsonFactory.getDefaultInstance(), assertion); assertEquals(CLIENT_EMAIL, signature.getPayload().getIssuer()); assertEquals(CLIENT_EMAIL, signature.getPayload().getSubject()); - assertEquals(JWT_AUDIENCE, signature.getPayload().getAudience()); + if (expectedScopeClaim != null) { + assertEquals(expectedScopeClaim, signature.getPayload().get("scope")); + assertFalse(signature.getPayload().containsKey("aud")); + } else { + assertEquals(JWT_AUDIENCE, signature.getPayload().getAudience()); + assertFalse(signature.getPayload().containsKey("scope")); + } assertEquals(PRIVATE_KEY_ID, signature.getHeader().getKeyId()); } diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java index 81b5f7de3..5020317f2 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java @@ -92,7 +92,6 @@ public class ServiceAccountJwtAccessCredentialsTest extends BaseSerializationTes private static final String JWT_ACCESS_PREFIX = ServiceAccountJwtAccessCredentials.JWT_ACCESS_PREFIX; private static final URI CALL_URI = URI.create("http://googleapis.com/testapi/v1/foo"); - private static final URI CALL_URI_AUDIENCE = URI.create("http://googleapis.com/"); private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance(); private static final String QUOTA_PROJECT = "sample-quota-project-id"; @@ -172,29 +171,6 @@ public void getAuthenticationType_returnsJwtAccess() throws IOException { assertEquals(credentials.getAuthenticationType(), "JWTAccess"); } - @Test - public void getUriForSelfSignedJWT() { - assertNull(ServiceAccountJwtAccessCredentials.getUriForSelfSignedJWT(null)); - - URI uri = URI.create("https://compute.googleapis.com/compute/v1/projects/"); - URI expected = URI.create("https://compute.googleapis.com/"); - assertEquals(expected, ServiceAccountJwtAccessCredentials.getUriForSelfSignedJWT(uri)); - } - - @Test - public void getUriForSelfSignedJWT_noHost() { - URI uri = URI.create("file:foo"); - URI expected = URI.create("file:foo"); - assertEquals(expected, ServiceAccountJwtAccessCredentials.getUriForSelfSignedJWT(uri)); - } - - @Test - public void getUriForSelfSignedJWT_forStaticAudience_returnsURI() { - URI uri = URI.create("compute.googleapis.com"); - URI expected = URI.create("compute.googleapis.com"); - assertEquals(expected, ServiceAccountJwtAccessCredentials.getUriForSelfSignedJWT(uri)); - } - @Test public void hasRequestMetadata_returnsTrue() throws IOException { Credentials credentials = @@ -224,7 +200,7 @@ public void getRequestMetadata_blocking_hasJwtAccess() throws IOException { Map> metadata = credentials.getRequestMetadata(CALL_URI); - verifyJwtAccess(metadata, SA_CLIENT_EMAIL, CALL_URI_AUDIENCE, SA_PRIVATE_KEY_ID); + verifyJwtAccess(metadata, SA_CLIENT_EMAIL, CALL_URI, SA_PRIVATE_KEY_ID); } @Test @@ -329,7 +305,7 @@ public void getRequestMetadata_async_hasJwtAccess() throws IOException { credentials.getRequestMetadata(CALL_URI, executor, callback); assertEquals(0, executor.numTasks()); assertNotNull(callback.metadata); - verifyJwtAccess(callback.metadata, SA_CLIENT_EMAIL, CALL_URI_AUDIENCE, SA_PRIVATE_KEY_ID); + verifyJwtAccess(callback.metadata, SA_CLIENT_EMAIL, CALL_URI, SA_PRIVATE_KEY_ID); } @Test @@ -678,7 +654,7 @@ public void fromStream_hasJwtAccess() throws IOException { assertNotNull(credentials); Map> metadata = credentials.getRequestMetadata(CALL_URI); - verifyJwtAccess(metadata, SA_CLIENT_EMAIL, CALL_URI_AUDIENCE, SA_PRIVATE_KEY_ID); + verifyJwtAccess(metadata, SA_CLIENT_EMAIL, CALL_URI, SA_PRIVATE_KEY_ID); } @Test