Skip to content

Commit f7df929

Browse files
authored
Adds accountId to STS credentials providers (#4040)
Adds accountId to STS credentials providers
1 parent 17a7da5 commit f7df929

File tree

25 files changed

+534
-93
lines changed

25 files changed

+534
-93
lines changed

core/auth/src/main/java/software/amazon/awssdk/auth/credentials/AwsBasicCredentials.java

Lines changed: 82 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,16 @@
1818
import static software.amazon.awssdk.utils.StringUtils.trimToNull;
1919

2020
import java.util.Objects;
21+
import java.util.Optional;
2122
import software.amazon.awssdk.annotations.Immutable;
2223
import software.amazon.awssdk.annotations.SdkInternalApi;
2324
import software.amazon.awssdk.annotations.SdkPublicApi;
2425
import software.amazon.awssdk.utils.ToString;
2526
import software.amazon.awssdk.utils.Validate;
2627

2728
/**
28-
* Provides access to the AWS credentials used for accessing services: AWS access key ID and secret access key. These
29-
* credentials are used to securely sign requests to services (e.g., AWS services) that use them for authentication.
29+
* Provides access to the AWS credentials used for accessing services: AWS access key ID and secret access key. These credentials
30+
* are used to securely sign requests to services (e.g., AWS services) that use them for authentication.
3031
*
3132
* <p>For more details on AWS access keys, see:
3233
* <a href="https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys">
@@ -39,14 +40,26 @@
3940
public final class AwsBasicCredentials implements AwsCredentials {
4041
/**
4142
* A set of AWS credentials without an access key or secret access key, indicating that anonymous access should be used.
42-
*
43+
* <p>
4344
* This should be accessed via {@link AnonymousCredentialsProvider#resolveCredentials()}.
4445
*/
4546
@SdkInternalApi
46-
static final AwsBasicCredentials ANONYMOUS_CREDENTIALS = new AwsBasicCredentials(null, null, false);
47+
static final AwsBasicCredentials ANONYMOUS_CREDENTIALS = builder().validateCredentials(false).build();
4748

4849
private final String accessKeyId;
4950
private final String secretAccessKey;
51+
private final String accountId;
52+
53+
private AwsBasicCredentials(Builder builder) {
54+
this.accessKeyId = trimToNull(builder.accessKeyId);
55+
this.secretAccessKey = trimToNull(builder.secretAccessKey);
56+
57+
if (builder.validateCredentials) {
58+
Validate.notNull(this.accessKeyId, "Access key ID cannot be blank.");
59+
Validate.notNull(this.secretAccessKey, "Secret access key cannot be blank.");
60+
}
61+
this.accountId = builder.accountId;
62+
}
5063

5164
/**
5265
* Constructs a new credentials object, with the specified AWS access key and AWS secret key.
@@ -55,27 +68,25 @@ public final class AwsBasicCredentials implements AwsCredentials {
5568
* @param secretAccessKey The AWS secret access key, used to authenticate the user interacting with AWS.
5669
*/
5770
protected AwsBasicCredentials(String accessKeyId, String secretAccessKey) {
58-
this(accessKeyId, secretAccessKey, true);
71+
this(builder().accessKeyId(accessKeyId)
72+
.secretAccessKey(secretAccessKey)
73+
.validateCredentials(true));
5974
}
6075

61-
private AwsBasicCredentials(String accessKeyId, String secretAccessKey, boolean validateCredentials) {
62-
this.accessKeyId = trimToNull(accessKeyId);
63-
this.secretAccessKey = trimToNull(secretAccessKey);
64-
65-
if (validateCredentials) {
66-
Validate.notNull(this.accessKeyId, "Access key ID cannot be blank.");
67-
Validate.notNull(this.secretAccessKey, "Secret access key cannot be blank.");
68-
}
76+
public static Builder builder() {
77+
return new Builder();
6978
}
7079

7180
/**
7281
* Constructs a new credentials object, with the specified AWS access key and AWS secret key.
7382
*
74-
* @param accessKeyId The AWS access key, used to identify the user interacting with AWS.
83+
* @param accessKeyId The AWS access key, used to identify the user interacting with AWS.
7584
* @param secretAccessKey The AWS secret access key, used to authenticate the user interacting with AWS.
76-
* */
85+
*/
7786
public static AwsBasicCredentials create(String accessKeyId, String secretAccessKey) {
78-
return new AwsBasicCredentials(accessKeyId, secretAccessKey);
87+
return builder().accessKeyId(accessKeyId)
88+
.secretAccessKey(secretAccessKey)
89+
.build();
7990
}
8091

8192
/**
@@ -94,10 +105,19 @@ public String secretAccessKey() {
94105
return secretAccessKey;
95106
}
96107

108+
/**
109+
* Retrieve the AWS account id associated with this credentials identity, if found.
110+
*/
111+
@Override
112+
public Optional<String> accountId() {
113+
return Optional.ofNullable(accountId);
114+
}
115+
97116
@Override
98117
public String toString() {
99118
return ToString.builder("AwsCredentials")
100119
.add("accessKeyId", accessKeyId)
120+
.add("accountId", accountId)
101121
.build();
102122
}
103123

@@ -111,14 +131,59 @@ public boolean equals(Object o) {
111131
}
112132
AwsBasicCredentials that = (AwsBasicCredentials) o;
113133
return Objects.equals(accessKeyId, that.accessKeyId) &&
114-
Objects.equals(secretAccessKey, that.secretAccessKey);
134+
Objects.equals(secretAccessKey, that.secretAccessKey) &&
135+
Objects.equals(accountId, that.accountId().orElse(null));
115136
}
116137

117138
@Override
118139
public int hashCode() {
119140
int hashCode = 1;
120141
hashCode = 31 * hashCode + Objects.hashCode(accessKeyId());
121142
hashCode = 31 * hashCode + Objects.hashCode(secretAccessKey());
143+
hashCode = 31 * hashCode + Objects.hashCode(accountId);
122144
return hashCode;
123145
}
146+
147+
public static final class Builder {
148+
private String accessKeyId;
149+
private String secretAccessKey;
150+
private String accountId;
151+
private boolean validateCredentials = true;
152+
153+
/**
154+
* The AWS access key, used to identify the user interacting with services.
155+
*/
156+
public Builder accessKeyId(String accessKeyId) {
157+
this.accessKeyId = accessKeyId;
158+
return this;
159+
}
160+
161+
/**
162+
* The AWS secret access key, used to authenticate the user interacting with services.
163+
*/
164+
public Builder secretAccessKey(String secretAccessKey) {
165+
this.secretAccessKey = secretAccessKey;
166+
return this;
167+
}
168+
169+
/**
170+
* The AWS account id associated with this credentials identity.
171+
*/
172+
public Builder accountId(String accountId) {
173+
this.accountId = accountId;
174+
return this;
175+
}
176+
177+
/**
178+
* Whether this class should verify that accessKeyId and secretAccessKey are not null.
179+
*/
180+
Builder validateCredentials(Boolean validateCredentials) {
181+
this.validateCredentials = validateCredentials;
182+
return this;
183+
}
184+
185+
public AwsBasicCredentials build() {
186+
return new AwsBasicCredentials(this);
187+
}
188+
}
124189
}

core/auth/src/main/java/software/amazon/awssdk/auth/credentials/AwsSessionCredentials.java

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515

1616
package software.amazon.awssdk.auth.credentials;
1717

18+
import java.time.Instant;
1819
import java.util.Objects;
20+
import java.util.Optional;
1921
import software.amazon.awssdk.annotations.Immutable;
2022
import software.amazon.awssdk.annotations.SdkPublicApi;
2123
import software.amazon.awssdk.identity.spi.AwsSessionCredentialsIdentity;
@@ -34,11 +36,19 @@ public final class AwsSessionCredentials implements AwsCredentials, AwsSessionCr
3436
private final String accessKeyId;
3537
private final String secretAccessKey;
3638
private final String sessionToken;
39+
private final String accountId;
40+
private final Instant expiration;
3741

38-
private AwsSessionCredentials(String accessKey, String secretKey, String sessionToken) {
39-
this.accessKeyId = Validate.paramNotNull(accessKey, "accessKey");
40-
this.secretAccessKey = Validate.paramNotNull(secretKey, "secretKey");
41-
this.sessionToken = Validate.paramNotNull(sessionToken, "sessionToken");
42+
private AwsSessionCredentials(Builder builder) {
43+
this.accessKeyId = Validate.paramNotNull(builder.accessKeyId, "accessKey");
44+
this.secretAccessKey = Validate.paramNotNull(builder.secretAccessKey, "secretKey");
45+
this.sessionToken = Validate.paramNotNull(builder.sessionToken, "sessionToken");
46+
this.accountId = builder.accountId;
47+
this.expiration = builder.expiration;
48+
}
49+
50+
public static Builder builder() {
51+
return new Builder();
4252
}
4353

4454
/**
@@ -50,7 +60,7 @@ private AwsSessionCredentials(String accessKey, String secretKey, String session
5060
* received temporary permission to access some resource.
5161
*/
5262
public static AwsSessionCredentials create(String accessKey, String secretKey, String sessionToken) {
53-
return new AwsSessionCredentials(accessKey, secretKey, sessionToken);
63+
return builder().accessKeyId(accessKey).secretAccessKey(secretKey).sessionToken(sessionToken).build();
5464
}
5565

5666
@Override
@@ -68,10 +78,20 @@ public String sessionToken() {
6878
return sessionToken;
6979
}
7080

81+
@Override
82+
public Optional<String> accountId() {
83+
return Optional.ofNullable(accountId);
84+
}
85+
86+
public Optional<Instant> expiration() {
87+
return Optional.ofNullable(expiration);
88+
}
89+
7190
@Override
7291
public String toString() {
7392
return ToString.builder("AwsSessionCredentials")
7493
.add("accessKeyId", accessKeyId())
94+
.add("accountId", accountId)
7595
.build();
7696
}
7797

@@ -87,7 +107,9 @@ public boolean equals(Object o) {
87107
AwsSessionCredentials that = (AwsSessionCredentials) o;
88108
return Objects.equals(accessKeyId, that.accessKeyId) &&
89109
Objects.equals(secretAccessKey, that.secretAccessKey) &&
90-
Objects.equals(sessionToken, that.sessionToken);
110+
Objects.equals(sessionToken, that.sessionToken) &&
111+
Objects.equals(accountId, that.accountId().orElse(null)) &&
112+
Objects.equals(expiration, that.expiration().orElse(null));
91113
}
92114

93115
@Override
@@ -96,6 +118,45 @@ public int hashCode() {
96118
hashCode = 31 * hashCode + Objects.hashCode(accessKeyId());
97119
hashCode = 31 * hashCode + Objects.hashCode(secretAccessKey());
98120
hashCode = 31 * hashCode + Objects.hashCode(sessionToken());
121+
hashCode = 31 * hashCode + Objects.hashCode(accountId);
122+
hashCode = 31 * hashCode + Objects.hashCode(expiration);
99123
return hashCode;
100124
}
125+
126+
public static final class Builder {
127+
private String accessKeyId;
128+
private String secretAccessKey;
129+
private String sessionToken;
130+
private String accountId;
131+
private Instant expiration;
132+
133+
public Builder accessKeyId(String accessKeyId) {
134+
this.accessKeyId = accessKeyId;
135+
return this;
136+
}
137+
138+
public Builder secretAccessKey(String secretAccessKey) {
139+
this.secretAccessKey = secretAccessKey;
140+
return this;
141+
}
142+
143+
public Builder sessionToken(String sessionToken) {
144+
this.sessionToken = sessionToken;
145+
return this;
146+
}
147+
148+
public Builder accountId(String accountId) {
149+
this.accountId = accountId;
150+
return this;
151+
}
152+
153+
public Builder expiration(Instant expiration) {
154+
this.expiration = expiration;
155+
return this;
156+
}
157+
158+
public AwsSessionCredentials build() {
159+
return new AwsSessionCredentials(this);
160+
}
161+
}
101162
}

core/auth/src/main/java/software/amazon/awssdk/auth/credentials/CredentialUtils.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,21 @@ public static AwsCredentials toCredentials(AwsCredentialsIdentity awsCredentials
7171
// identity-spi defines 2 known types - AwsCredentialsIdentity and a sub-type AwsSessionCredentialsIdentity
7272
if (awsCredentialsIdentity instanceof AwsSessionCredentialsIdentity) {
7373
AwsSessionCredentialsIdentity awsSessionCredentialsIdentity = (AwsSessionCredentialsIdentity) awsCredentialsIdentity;
74-
return AwsSessionCredentials.create(awsSessionCredentialsIdentity.accessKeyId(),
75-
awsSessionCredentialsIdentity.secretAccessKey(),
76-
awsSessionCredentialsIdentity.sessionToken());
74+
return AwsSessionCredentials.builder()
75+
.accessKeyId(awsSessionCredentialsIdentity.accessKeyId())
76+
.secretAccessKey(awsSessionCredentialsIdentity.secretAccessKey())
77+
.sessionToken(awsSessionCredentialsIdentity.sessionToken())
78+
.accountId(awsSessionCredentialsIdentity.accountId().orElse(null))
79+
.build();
7780
}
7881
if (isAnonymous(awsCredentialsIdentity)) {
7982
return AwsBasicCredentials.ANONYMOUS_CREDENTIALS;
8083
}
81-
return AwsBasicCredentials.create(awsCredentialsIdentity.accessKeyId(),
82-
awsCredentialsIdentity.secretAccessKey());
84+
return AwsBasicCredentials.builder()
85+
.accessKeyId(awsCredentialsIdentity.accessKeyId())
86+
.secretAccessKey(awsCredentialsIdentity.secretAccessKey())
87+
.accountId(awsCredentialsIdentity.accountId().orElse(null))
88+
.build();
8389
}
8490

8591
/**

core/auth/src/test/java/software/amazon/awssdk/auth/credentials/StaticCredentialsProviderTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
public class StaticCredentialsProviderTest {
2323
@Test
2424
public void getAwsCredentials_ReturnsSameCredentials() throws Exception {
25-
final AwsCredentials credentials = new AwsBasicCredentials("akid", "skid");
25+
final AwsCredentials credentials = AwsBasicCredentials.create("akid", "skid");
2626
final AwsCredentials actualCredentials =
2727
StaticCredentialsProvider.create(credentials).resolveCredentials();
2828
assertEquals(credentials, actualCredentials);

0 commit comments

Comments
 (0)