Skip to content

Commit 05b5f19

Browse files
authored
Merge branch 'main' into main
2 parents d7ca3d4 + 6668022 commit 05b5f19

File tree

21 files changed

+888
-178
lines changed

21 files changed

+888
-178
lines changed

.github/workflows/auto-release.yaml

Lines changed: 0 additions & 103 deletions
This file was deleted.

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# Changelog
22

3+
## [1.29.0](https://github.com/googleapis/google-auth-library-java/compare/v1.28.0...v1.29.0) (2024-10-22)
4+
5+
6+
### Features
7+
8+
* Service sccount to service account impersonation to support universe domain ([#1528](https://github.com/googleapis/google-auth-library-java/issues/1528)) ([c498ccf](https://github.com/googleapis/google-auth-library-java/commit/c498ccf67755c6ec619cb37962c2c86ae3ec9d4c))
9+
10+
11+
### Bug Fixes
12+
13+
* Make some enum fields final ([#1526](https://github.com/googleapis/google-auth-library-java/issues/1526)) ([8920155](https://github.com/googleapis/google-auth-library-java/commit/89201558db913d9a71b3acccbab8eb0045ada6de))
14+
315
## [1.28.0](https://github.com/googleapis/google-auth-library-java/compare/v1.27.0...v1.28.0) (2024-10-02)
416

517

appengine/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>com.google.auth</groupId>
77
<artifactId>google-auth-library-parent</artifactId>
8-
<version>1.28.1-SNAPSHOT</version><!-- {x-version-update:google-auth-library-parent:current} -->
8+
<version>1.29.1-SNAPSHOT</version><!-- {x-version-update:google-auth-library-parent:current} -->
99
<relativePath>../pom.xml</relativePath>
1010
</parent>
1111

bom/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>com.google.auth</groupId>
55
<artifactId>google-auth-library-bom</artifactId>
6-
<version>1.28.1-SNAPSHOT</version><!-- {x-version-update:google-auth-library-bom:current} -->
6+
<version>1.29.1-SNAPSHOT</version><!-- {x-version-update:google-auth-library-bom:current} -->
77
<packaging>pom</packaging>
88
<name>Google Auth Library for Java BOM</name>
99
<description>
@@ -91,7 +91,7 @@
9191
<plugin>
9292
<groupId>org.apache.maven.plugins</groupId>
9393
<artifactId>maven-site-plugin</artifactId>
94-
<version>3.20.0</version>
94+
<version>3.21.0</version>
9595
<configuration>
9696
<skip>true</skip>
9797
</configuration>

credentials/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<parent>
55
<groupId>com.google.auth</groupId>
66
<artifactId>google-auth-library-parent</artifactId>
7-
<version>1.28.1-SNAPSHOT</version><!-- {x-version-update:google-auth-library-parent:current} -->
7+
<version>1.29.1-SNAPSHOT</version><!-- {x-version-update:google-auth-library-parent:current} -->
88
<relativePath>../pom.xml</relativePath>
99
</parent>
1010

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ public static String getTokenServerEncodedUrl() {
507507

508508
public static String getUniverseDomainUrl() {
509509
return getMetadataServerUrl(DefaultCredentialsProvider.DEFAULT)
510-
+ "/computeMetadata/v1/universe/universe_domain";
510+
+ "/computeMetadata/v1/universe/universe-domain";
511511
}
512512

513513
public static String getServiceAccountsUrl() {

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,11 +263,11 @@ protected boolean isExplicitUniverseDomain() {
263263
/**
264264
* Checks if universe domain equals to {@link Credentials#GOOGLE_DEFAULT_UNIVERSE}.
265265
*
266-
* @return true if universeDomain equals to {@link Credentials#GOOGLE_DEFAULT_UNIVERSE}, false
266+
* @return true if universe domain equals to {@link Credentials#GOOGLE_DEFAULT_UNIVERSE}, false
267267
* otherwise
268268
*/
269-
boolean isDefaultUniverseDomain() {
270-
return this.universeDomain.equals(Credentials.GOOGLE_DEFAULT_UNIVERSE);
269+
boolean isDefaultUniverseDomain() throws IOException {
270+
return getUniverseDomain().equals(Credentials.GOOGLE_DEFAULT_UNIVERSE);
271271
}
272272

273273
/**

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

Lines changed: 71 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,6 @@ public class ImpersonatedCredentials extends GoogleCredentials
103103
private static final int DEFAULT_LIFETIME_IN_SECONDS = 3600;
104104
private static final String CLOUD_PLATFORM_SCOPE =
105105
"https://www.googleapis.com/auth/cloud-platform";
106-
private static final String IAM_ACCESS_TOKEN_ENDPOINT =
107-
"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/%s:generateAccessToken";
108-
109106
private GoogleCredentials sourceCredentials;
110107
private String targetPrincipal;
111108
private List<String> delegates;
@@ -423,14 +420,7 @@ public boolean createScopedRequired() {
423420

424421
@Override
425422
public GoogleCredentials createScoped(Collection<String> scopes) {
426-
return toBuilder()
427-
.setScopes(new ArrayList<>(scopes))
428-
.setLifetime(this.lifetime)
429-
.setDelegates(this.delegates)
430-
.setHttpTransportFactory(this.transportFactory)
431-
.setQuotaProjectId(this.quotaProjectId)
432-
.setIamEndpointOverride(this.iamEndpointOverride)
433-
.build();
423+
return toBuilder().setScopes(new ArrayList<>(scopes)).setAccessToken(null).build();
434424
}
435425

436426
@Override
@@ -457,7 +447,7 @@ public ImpersonatedCredentials createWithCustomCalendar(Calendar calendar) {
457447
.build();
458448
}
459449

460-
private ImpersonatedCredentials(Builder builder) {
450+
private ImpersonatedCredentials(Builder builder) throws IOException {
461451
super(builder);
462452
this.sourceCredentials = builder.getSourceCredentials();
463453
this.targetPrincipal = builder.getTargetPrincipal();
@@ -472,14 +462,36 @@ private ImpersonatedCredentials(Builder builder) {
472462
this.transportFactoryClassName = this.transportFactory.getClass().getName();
473463
this.calendar = builder.getCalendar();
474464
if (this.delegates == null) {
475-
this.delegates = new ArrayList<String>();
465+
this.delegates = new ArrayList<>();
476466
}
477467
if (this.scopes == null) {
478468
throw new IllegalStateException("Scopes cannot be null");
479469
}
480470
if (this.lifetime > TWELVE_HOURS_IN_SECONDS) {
481471
throw new IllegalStateException("lifetime must be less than or equal to 43200");
482472
}
473+
474+
// Do not expect explicit universe domain, throw exception if the explicit universe domain
475+
// does not match the source credential.
476+
// Do nothing if it matches the source credential
477+
if (isExplicitUniverseDomain()
478+
&& !this.sourceCredentials.getUniverseDomain().equals(builder.getUniverseDomain())) {
479+
throw new IllegalStateException(
480+
String.format(
481+
"Universe domain %s in source credentials "
482+
+ "does not match %s universe domain set for impersonated credentials.",
483+
this.sourceCredentials.getUniverseDomain(), builder.getUniverseDomain()));
484+
}
485+
}
486+
487+
/**
488+
* Gets the universe domain for the credential.
489+
*
490+
* @return the universe domain from source credentials
491+
*/
492+
@Override
493+
public String getUniverseDomain() throws IOException {
494+
return this.sourceCredentials.getUniverseDomain();
483495
}
484496

485497
@Override
@@ -489,10 +501,18 @@ public AccessToken refreshAccessToken() throws IOException {
489501
this.sourceCredentials.createScoped(Arrays.asList(CLOUD_PLATFORM_SCOPE));
490502
}
491503

492-
try {
493-
this.sourceCredentials.refreshIfExpired();
494-
} catch (IOException e) {
495-
throw new IOException("Unable to refresh sourceCredentials", e);
504+
// skip for SA with SSJ flow because it uses self-signed JWT
505+
// and will get refreshed at initialize request step
506+
// run for other source credential types or SA with GDU assert flow
507+
if (!(this.sourceCredentials instanceof ServiceAccountCredentials)
508+
|| (isDefaultUniverseDomain()
509+
&& ((ServiceAccountCredentials) this.sourceCredentials)
510+
.shouldUseAssertionFlowForGdu())) {
511+
try {
512+
this.sourceCredentials.refreshIfExpired();
513+
} catch (IOException e) {
514+
throw new IOException("Unable to refresh sourceCredentials", e);
515+
}
496516
}
497517

498518
HttpTransport httpTransport = this.transportFactory.create();
@@ -504,7 +524,11 @@ public AccessToken refreshAccessToken() throws IOException {
504524
String endpointUrl =
505525
this.iamEndpointOverride != null
506526
? this.iamEndpointOverride
507-
: String.format(IAM_ACCESS_TOKEN_ENDPOINT, this.targetPrincipal);
527+
: String.format(
528+
OAuth2Utils.IAM_ACCESS_TOKEN_ENDPOINT_FORMAT,
529+
getUniverseDomain(),
530+
this.targetPrincipal);
531+
508532
GenericUrl url = new GenericUrl(endpointUrl);
509533

510534
Map<String, Object> body =
@@ -603,6 +627,9 @@ public boolean equals(Object obj) {
603627
if (!(obj instanceof ImpersonatedCredentials)) {
604628
return false;
605629
}
630+
if (!super.equals(obj)) {
631+
return false;
632+
}
606633
ImpersonatedCredentials other = (ImpersonatedCredentials) obj;
607634
return Objects.equals(this.sourceCredentials, other.sourceCredentials)
608635
&& Objects.equals(this.targetPrincipal, other.targetPrincipal)
@@ -616,7 +643,7 @@ public boolean equals(Object obj) {
616643

617644
@Override
618645
public Builder toBuilder() {
619-
return new Builder(this.sourceCredentials, this.targetPrincipal);
646+
return new Builder(this);
620647
}
621648

622649
public static Builder newBuilder() {
@@ -636,11 +663,29 @@ public static class Builder extends GoogleCredentials.Builder {
636663

637664
protected Builder() {}
638665

666+
/**
667+
* @param sourceCredentials The source credentials to use for impersonation.
668+
* @param targetPrincipal The service account to impersonate.
669+
* @deprecated Use {@link #Builder(ImpersonatedCredentials)} instead. This constructor will be
670+
* removed in a future release.
671+
*/
672+
@Deprecated
639673
protected Builder(GoogleCredentials sourceCredentials, String targetPrincipal) {
640674
this.sourceCredentials = sourceCredentials;
641675
this.targetPrincipal = targetPrincipal;
642676
}
643677

678+
protected Builder(ImpersonatedCredentials credentials) {
679+
super(credentials);
680+
this.sourceCredentials = credentials.sourceCredentials;
681+
this.targetPrincipal = credentials.targetPrincipal;
682+
this.delegates = credentials.delegates;
683+
this.scopes = credentials.scopes;
684+
this.lifetime = credentials.lifetime;
685+
this.transportFactory = credentials.transportFactory;
686+
this.iamEndpointOverride = credentials.iamEndpointOverride;
687+
}
688+
644689
@CanIgnoreReturnValue
645690
public Builder setSourceCredentials(GoogleCredentials sourceCredentials) {
646691
this.sourceCredentials = sourceCredentials;
@@ -726,7 +771,13 @@ public Calendar getCalendar() {
726771

727772
@Override
728773
public ImpersonatedCredentials build() {
729-
return new ImpersonatedCredentials(this);
774+
try {
775+
return new ImpersonatedCredentials(this);
776+
} catch (IOException e) {
777+
// throwing exception would be breaking change. catching instead.
778+
// this should never happen.
779+
throw new IllegalStateException(e);
780+
}
730781
}
731782
}
732783

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ class OAuth2Utils {
8181
static final String IAM_ID_TOKEN_ENDPOINT_FORMAT =
8282
"https://iamcredentials.%s/v1/projects/-/serviceAccounts/%s:generateIdToken";
8383

84+
static final String IAM_ACCESS_TOKEN_ENDPOINT_FORMAT =
85+
"https://iamcredentials.%s/v1/projects/-/serviceAccounts/%s:generateAccessToken";
86+
static final String SIGN_BLOB_ENDPOINT_FORMAT =
87+
"https://iamcredentials.%s/v1/projects/-/serviceAccounts/%s:signBlob";
88+
8489
static final URI TOKEN_SERVER_URI = URI.create("https://oauth2.googleapis.com/token");
8590

8691
static final URI TOKEN_REVOKE_URI = URI.create("https://oauth2.googleapis.com/revoke");

0 commit comments

Comments
 (0)