Skip to content

Commit e87ed31

Browse files
committed
feat: support ability to set universe domain in ServiceAccountJwtAccessCredentials
1 parent 6c311e2 commit e87ed31

File tree

2 files changed

+60
-15
lines changed

2 files changed

+60
-15
lines changed

oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ public class ServiceAccountJwtAccessCredentials extends Credentials
8888
private final String privateKeyId;
8989
private final URI defaultAudience;
9090
private final String quotaProjectId;
91+
private final String universeDomain;
9192

9293
private transient LoadingCache<JwtClaims, JwtCredentials> credentialsCache;
9394

@@ -103,8 +104,8 @@ public class ServiceAccountJwtAccessCredentials extends Credentials
103104
* @param privateKeyId Private key identifier for the service account. May be null.
104105
*/
105106
private ServiceAccountJwtAccessCredentials(
106-
String clientId, String clientEmail, PrivateKey privateKey, String privateKeyId) {
107-
this(clientId, clientEmail, privateKey, privateKeyId, null, null);
107+
String clientId, String clientEmail, PrivateKey privateKey, String privateKeyId) {
108+
this(clientId, clientEmail, privateKey, privateKeyId, null, null,Credentials.GOOGLE_DEFAULT_UNIVERSE);
108109
}
109110

110111
/**
@@ -115,21 +116,28 @@ private ServiceAccountJwtAccessCredentials(
115116
* @param privateKey RSA private key object for the service account.
116117
* @param privateKeyId Private key identifier for the service account. May be null.
117118
* @param defaultAudience Audience to use if not provided by transport. May be null.
119+
* @param universeDomain Universe domain
118120
*/
119121
private ServiceAccountJwtAccessCredentials(
120122
String clientId,
121123
String clientEmail,
122124
PrivateKey privateKey,
123125
String privateKeyId,
124126
URI defaultAudience,
125-
String quotaProjectId) {
127+
String quotaProjectId,
128+
String universeDomain) {
126129
this.clientId = clientId;
127130
this.clientEmail = Preconditions.checkNotNull(clientEmail);
128131
this.privateKey = Preconditions.checkNotNull(privateKey);
129132
this.privateKeyId = privateKeyId;
130133
this.defaultAudience = defaultAudience;
131134
this.credentialsCache = createCache();
132135
this.quotaProjectId = quotaProjectId;
136+
if (universeDomain == null || universeDomain.trim().isEmpty()) {
137+
this.universeDomain = Credentials.GOOGLE_DEFAULT_UNIVERSE;
138+
} else {
139+
this.universeDomain = universeDomain;
140+
}
133141
}
134142

135143
/**
@@ -160,6 +168,9 @@ static ServiceAccountJwtAccessCredentials fromJson(Map<String, Object> json, URI
160168
String privateKeyPkcs8 = (String) json.get("private_key");
161169
String privateKeyId = (String) json.get("private_key_id");
162170
String quoataProjectId = (String) json.get("quota_project_id");
171+
String rawUniverseDomain = (String) json.get("universe_domain");
172+
String resolvedUniverseDomain = (rawUniverseDomain == null) ? Credentials.GOOGLE_DEFAULT_UNIVERSE : rawUniverseDomain;
173+
163174
if (clientId == null
164175
|| clientEmail == null
165176
|| privateKeyPkcs8 == null
@@ -169,9 +180,10 @@ static ServiceAccountJwtAccessCredentials fromJson(Map<String, Object> json, URI
169180
+ "expecting 'client_id', 'client_email', 'private_key' and 'private_key_id'.");
170181
}
171182
return ServiceAccountJwtAccessCredentials.fromPkcs8(
172-
clientId, clientEmail, privateKeyPkcs8, privateKeyId, defaultAudience, quoataProjectId);
183+
clientId, clientEmail, privateKeyPkcs8, privateKeyId, defaultAudience, quoataProjectId, resolvedUniverseDomain);
173184
}
174185

186+
175187
/**
176188
* Factory using PKCS#8 for the private key.
177189
*
@@ -207,7 +219,7 @@ public static ServiceAccountJwtAccessCredentials fromPkcs8(
207219
URI defaultAudience)
208220
throws IOException {
209221
return ServiceAccountJwtAccessCredentials.fromPkcs8(
210-
clientId, clientEmail, privateKeyPkcs8, privateKeyId, defaultAudience, null);
222+
clientId, clientEmail, privateKeyPkcs8, privateKeyId, defaultAudience, null, Credentials.GOOGLE_DEFAULT_UNIVERSE);
211223
}
212224

213225
static ServiceAccountJwtAccessCredentials fromPkcs8(
@@ -216,11 +228,12 @@ static ServiceAccountJwtAccessCredentials fromPkcs8(
216228
String privateKeyPkcs8,
217229
String privateKeyId,
218230
URI defaultAudience,
219-
String quotaProjectId)
231+
String quotaProjectId,
232+
String universeDomain)
220233
throws IOException {
221234
PrivateKey privateKey = OAuth2Utils.privateKeyFromPkcs8(privateKeyPkcs8);
222235
return new ServiceAccountJwtAccessCredentials(
223-
clientId, clientEmail, privateKey, privateKeyId, defaultAudience, quotaProjectId);
236+
clientId, clientEmail, privateKey, privateKeyId, defaultAudience, quotaProjectId, universeDomain);
224237
}
225238

226239
/**
@@ -352,22 +365,21 @@ public Map<String, List<String>> getRequestMetadata(URI uri) throws IOException
352365
+ "defaultAudience to be specified");
353366
}
354367
}
355-
356368
try {
357369
JwtClaims defaultClaims =
358-
JwtClaims.newBuilder()
359-
.setAudience(uri.toString())
360-
.setIssuer(clientEmail)
361-
.setSubject(clientEmail)
362-
.build();
370+
JwtClaims.newBuilder()
371+
.setAudience(uri.toString())
372+
.setIssuer(clientEmail)
373+
.setSubject(clientEmail)
374+
.build();
363375
JwtCredentials credentials = credentialsCache.get(defaultClaims);
364376
Map<String, List<String>> requestMetadata = credentials.getRequestMetadata(uri);
365377
return addQuotaProjectIdToRequestMetadata(quotaProjectId, requestMetadata);
366378
} catch (ExecutionException e) {
367379
Throwables.propagateIfPossible(e.getCause(), IOException.class);
368380
// Should never happen
369381
throw new IllegalStateException(
370-
"generateJwtAccess threw an unexpected checked exception", e.getCause());
382+
"generateJwtAccess threw an unexpected checked exception", e.getCause());
371383

372384
} catch (UncheckedExecutionException e) {
373385
Throwables.throwIfUnchecked(e);
@@ -399,6 +411,10 @@ public final String getPrivateKeyId() {
399411
return privateKeyId;
400412
}
401413

414+
public final String getUniverseDomain() {
415+
return universeDomain;
416+
}
417+
402418
@Override
403419
public String getAccount() {
404420
return getClientEmail();
@@ -474,6 +490,7 @@ public static class Builder {
474490
private String privateKeyId;
475491
private URI defaultAudience;
476492
private String quotaProjectId;
493+
private String universeDomain;
477494

478495
protected Builder() {}
479496

@@ -484,6 +501,7 @@ protected Builder(ServiceAccountJwtAccessCredentials credentials) {
484501
this.privateKeyId = credentials.privateKeyId;
485502
this.defaultAudience = credentials.defaultAudience;
486503
this.quotaProjectId = credentials.quotaProjectId;
504+
this.universeDomain = credentials.universeDomain;
487505
}
488506

489507
@CanIgnoreReturnValue
@@ -522,6 +540,13 @@ public Builder setQuotaProjectId(String quotaProjectId) {
522540
return this;
523541
}
524542

543+
@CanIgnoreReturnValue
544+
public Builder setUniverseDomain(String universeDomain) {
545+
this.universeDomain = universeDomain;
546+
return this;
547+
}
548+
549+
525550
public String getClientId() {
526551
return clientId;
527552
}
@@ -546,9 +571,13 @@ public String getQuotaProjectId() {
546571
return quotaProjectId;
547572
}
548573

574+
public String getUniverseDomain() {
575+
return universeDomain;
576+
}
577+
549578
public ServiceAccountJwtAccessCredentials build() {
550579
return new ServiceAccountJwtAccessCredentials(
551-
clientId, clientEmail, privateKey, privateKeyId, defaultAudience, quotaProjectId);
580+
clientId, clientEmail, privateKey, privateKeyId, defaultAudience, quotaProjectId, universeDomain);
552581
}
553582
}
554583
}

oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
package com.google.auth.oauth2;
3333

34+
import static com.google.auth.Credentials.GOOGLE_DEFAULT_UNIVERSE;
3435
import static org.junit.Assert.assertArrayEquals;
3536
import static org.junit.Assert.assertEquals;
3637
import static org.junit.Assert.assertFalse;
@@ -111,6 +112,7 @@ public void constructor_allParameters_constructs() throws IOException {
111112
assertEquals(privateKey, credentials.getPrivateKey());
112113
assertEquals(SA_PRIVATE_KEY_ID, credentials.getPrivateKeyId());
113114
assertEquals(QUOTA_PROJECT, credentials.getQuotaProjectId());
115+
assertEquals(GOOGLE_DEFAULT_UNIVERSE, credentials.getUniverseDomain());
114116
}
115117

116118
@Test
@@ -829,6 +831,20 @@ public void onFailure(Throwable exception) {
829831
assertTrue("Should have run onSuccess() callback", success.get());
830832
}
831833

834+
@Test
835+
public void getUniverseDomain_defaultUniverse() throws IOException {
836+
PrivateKey privateKey = OAuth2Utils.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8);
837+
ServiceAccountJwtAccessCredentials credentials =
838+
ServiceAccountJwtAccessCredentials.newBuilder()
839+
.setClientId(SA_CLIENT_ID)
840+
.setClientEmail(SA_CLIENT_EMAIL)
841+
.setPrivateKey(privateKey)
842+
.setPrivateKeyId(SA_PRIVATE_KEY_ID)
843+
.setDefaultAudience(URI.create("default-audience"))
844+
.build();
845+
assertEquals(GOOGLE_DEFAULT_UNIVERSE, credentials.getUniverseDomain());
846+
}
847+
832848
private void verifyJwtAccess(
833849
Map<String, List<String>> metadata,
834850
String expectedEmail,

0 commit comments

Comments
 (0)