Skip to content

Commit d3e828a

Browse files
authored
Recording identity provider names in user agent string (#5047)
* Adding source to identity (provider name) (#5008) * Adding identity provider source to user agent string (#5029) * Adds provider name to all SDK identity providers (#5040)
1 parent 34f4743 commit d3e828a

File tree

60 files changed

+1267
-266
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1267
-266
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"type": "feature",
3+
"category": "AWS SDK for Java v2",
4+
"contributor": "",
5+
"description": "Records identity provider names in a resolved identity and adds this information to the user agent string"
6+
}

build-tools/src/main/resources/software/amazon/awssdk/spotbugs-suppressions.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,11 @@
293293
<Bug pattern="NP_BOOLEAN_RETURN_NULL"/>
294294
</Match>
295295

296+
<Match>
297+
<Class name="software.amazon.awssdk.auth.credentials.AwsSessionCredentials$Builder"/>
298+
<Bug pattern="BAD_TO_BUILDER"/>
299+
</Match>
300+
296301
<!-- New flags as of spotbogs 4.7.3.5 -->
297302
<!-- TODO: Fix or explicitly exclude each occurrence -->
298303
<Match>

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
@SdkPublicApi
2626
public final class AnonymousCredentialsProvider implements AwsCredentialsProvider {
2727

28+
private static final String PROVIDER_NAME = "AnonymousCredentialsProvider";
29+
2830
private AnonymousCredentialsProvider() {
2931
}
3032

@@ -34,11 +36,14 @@ public static AnonymousCredentialsProvider create() {
3436

3537
@Override
3638
public AwsCredentials resolveCredentials() {
37-
return AwsBasicCredentials.ANONYMOUS_CREDENTIALS;
39+
return AwsBasicCredentials.builder()
40+
.validateCredentials(false)
41+
.providerName(PROVIDER_NAME)
42+
.build();
3843
}
3944

4045
@Override
4146
public String toString() {
42-
return ToString.create("AnonymousCredentialsProvider");
47+
return ToString.create(PROVIDER_NAME);
4348
}
4449
}

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

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

2020
import java.util.Objects;
21+
import java.util.Optional;
22+
import java.util.function.Consumer;
2123
import software.amazon.awssdk.annotations.Immutable;
2224
import software.amazon.awssdk.annotations.SdkInternalApi;
2325
import software.amazon.awssdk.annotations.SdkPublicApi;
2426
import software.amazon.awssdk.utils.ToString;
2527
import software.amazon.awssdk.utils.Validate;
28+
import software.amazon.awssdk.utils.builder.CopyableBuilder;
29+
import software.amazon.awssdk.utils.builder.ToCopyableBuilder;
2630

2731
/**
2832
* Provides access to the AWS credentials used for accessing services: AWS access key ID and secret access key. These
@@ -36,17 +40,31 @@
3640
*/
3741
@Immutable
3842
@SdkPublicApi
39-
public final class AwsBasicCredentials implements AwsCredentials {
43+
public final class AwsBasicCredentials implements AwsCredentials,
44+
ToCopyableBuilder<AwsBasicCredentials.Builder, AwsBasicCredentials> {
4045
/**
4146
* A set of AWS credentials without an access key or secret access key, indicating that anonymous access should be used.
42-
*
43-
* This should be accessed via {@link AnonymousCredentialsProvider#resolveCredentials()}.
4447
*/
48+
// TODO(sra-identity-and-auth): Check if this static member can be removed after cleanup
4549
@SdkInternalApi
46-
static final AwsBasicCredentials ANONYMOUS_CREDENTIALS = new AwsBasicCredentials(null, null, false);
50+
static final AwsBasicCredentials ANONYMOUS_CREDENTIALS = builder().validateCredentials(false).build();
4751

4852
private final String accessKeyId;
4953
private final String secretAccessKey;
54+
private final boolean validateCredentials;
55+
private final String providerName;
56+
57+
private AwsBasicCredentials(Builder builder) {
58+
this.accessKeyId = trimToNull(builder.accessKeyId);
59+
this.secretAccessKey = trimToNull(builder.secretAccessKey);
60+
this.validateCredentials = builder.validateCredentials;
61+
this.providerName = builder.providerName;
62+
63+
if (builder.validateCredentials) {
64+
Validate.notNull(this.accessKeyId, "Access key ID cannot be blank.");
65+
Validate.notNull(this.secretAccessKey, "Secret access key cannot be blank.");
66+
}
67+
}
5068

5169
/**
5270
* Constructs a new credentials object, with the specified AWS access key and AWS secret key.
@@ -55,17 +73,14 @@ public final class AwsBasicCredentials implements AwsCredentials {
5573
* @param secretAccessKey The AWS secret access key, used to authenticate the user interacting with AWS.
5674
*/
5775
protected AwsBasicCredentials(String accessKeyId, String secretAccessKey) {
58-
this(accessKeyId, secretAccessKey, true);
59-
}
60-
61-
private AwsBasicCredentials(String accessKeyId, String secretAccessKey, boolean validateCredentials) {
6276
this.accessKeyId = trimToNull(accessKeyId);
6377
this.secretAccessKey = trimToNull(secretAccessKey);
78+
this.validateCredentials = false;
79+
this.providerName = null;
80+
}
6481

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-
}
82+
public static Builder builder() {
83+
return new Builder();
6984
}
7085

7186
/**
@@ -75,7 +90,9 @@ private AwsBasicCredentials(String accessKeyId, String secretAccessKey, boolean
7590
* @param secretAccessKey The AWS secret access key, used to authenticate the user interacting with AWS.
7691
* */
7792
public static AwsBasicCredentials create(String accessKeyId, String secretAccessKey) {
78-
return new AwsBasicCredentials(accessKeyId, secretAccessKey);
93+
return builder().accessKeyId(accessKeyId)
94+
.secretAccessKey(secretAccessKey)
95+
.build();
7996
}
8097

8198
/**
@@ -94,10 +111,19 @@ public String secretAccessKey() {
94111
return secretAccessKey;
95112
}
96113

114+
/**
115+
* The name of the identity provider that created this credential identity.
116+
*/
117+
@Override
118+
public Optional<String> providerName() {
119+
return Optional.ofNullable(providerName);
120+
}
121+
97122
@Override
98123
public String toString() {
99124
return ToString.builder("AwsCredentials")
100125
.add("accessKeyId", accessKeyId)
126+
.add("providerName", providerName)
101127
.build();
102128
}
103129

@@ -121,4 +147,69 @@ public int hashCode() {
121147
hashCode = 31 * hashCode + Objects.hashCode(secretAccessKey());
122148
return hashCode;
123149
}
150+
151+
@Override
152+
public Builder toBuilder() {
153+
return builder().accessKeyId(accessKeyId)
154+
.secretAccessKey(secretAccessKey)
155+
.validateCredentials(validateCredentials)
156+
.providerName(providerName);
157+
}
158+
159+
@Override
160+
public AwsBasicCredentials copy(Consumer<? super AwsBasicCredentials.Builder> modifier) {
161+
return ToCopyableBuilder.super.copy(modifier);
162+
}
163+
164+
/**
165+
* A builder for creating an instance of {@link AwsBasicCredentials}. This can be created with the static
166+
* {@link #builder()} method.
167+
*/
168+
public static final class Builder implements CopyableBuilder<AwsBasicCredentials.Builder, AwsBasicCredentials> {
169+
private String accessKeyId;
170+
private String secretAccessKey;
171+
private String providerName;
172+
private boolean validateCredentials = true;
173+
174+
private Builder() {
175+
}
176+
177+
/**
178+
* The AWS access key, used to identify the user interacting with services.
179+
*/
180+
public Builder accessKeyId(String accessKeyId) {
181+
this.accessKeyId = accessKeyId;
182+
return this;
183+
}
184+
185+
/**
186+
* The AWS secret access key, used to authenticate the user interacting with services.
187+
*/
188+
public Builder secretAccessKey(String secretAccessKey) {
189+
this.secretAccessKey = secretAccessKey;
190+
return this;
191+
}
192+
193+
/**
194+
* The name of the identity provider that created this credential identity.
195+
*/
196+
public Builder providerName(String providerName) {
197+
this.providerName = providerName;
198+
return this;
199+
}
200+
201+
/**
202+
* Whether this class should verify that accessKeyId and secretAccessKey are not null.
203+
* Used internally by the SDK for legacy reasons.
204+
*/
205+
@SdkInternalApi
206+
public Builder validateCredentials(Boolean validateCredentials) {
207+
this.validateCredentials = validateCredentials;
208+
return this;
209+
}
210+
211+
public AwsBasicCredentials build() {
212+
return new AwsBasicCredentials(this);
213+
}
214+
}
124215
}

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

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@
1818
import java.time.Instant;
1919
import java.util.Objects;
2020
import java.util.Optional;
21+
import java.util.function.Consumer;
2122
import software.amazon.awssdk.annotations.Immutable;
2223
import software.amazon.awssdk.annotations.SdkPublicApi;
2324
import software.amazon.awssdk.identity.spi.AwsSessionCredentialsIdentity;
2425
import software.amazon.awssdk.utils.ToString;
2526
import software.amazon.awssdk.utils.Validate;
27+
import software.amazon.awssdk.utils.builder.CopyableBuilder;
28+
import software.amazon.awssdk.utils.builder.ToCopyableBuilder;
2629

2730
/**
2831
* A special type of {@link AwsCredentials} that provides a session token to be used in service authentication. Session
@@ -31,19 +34,21 @@
3134
*/
3235
@Immutable
3336
@SdkPublicApi
34-
public final class AwsSessionCredentials implements AwsCredentials, AwsSessionCredentialsIdentity {
35-
37+
public final class AwsSessionCredentials implements AwsCredentials, AwsSessionCredentialsIdentity,
38+
ToCopyableBuilder<AwsSessionCredentials.Builder, AwsSessionCredentials> {
3639
private final String accessKeyId;
3740
private final String secretAccessKey;
3841
private final String sessionToken;
3942

4043
private final Instant expirationTime;
44+
private final String providerName;
4145

4246
private AwsSessionCredentials(Builder builder) {
4347
this.accessKeyId = Validate.paramNotNull(builder.accessKeyId, "accessKey");
4448
this.secretAccessKey = Validate.paramNotNull(builder.secretAccessKey, "secretKey");
4549
this.sessionToken = Validate.paramNotNull(builder.sessionToken, "sessionToken");
4650
this.expirationTime = builder.expirationTime;
51+
this.providerName = builder.providerName;
4752
}
4853

4954
/**
@@ -93,14 +98,24 @@ public Optional<Instant> expirationTime() {
9398
* Retrieve the AWS session token. This token is retrieved from an AWS token service, and is used for authenticating that this
9499
* user has received temporary permission to access some resource.
95100
*/
101+
@Override
96102
public String sessionToken() {
97103
return sessionToken;
98104
}
99105

106+
/**
107+
* The name of the identity provider that created this credential identity.
108+
*/
109+
@Override
110+
public Optional<String> providerName() {
111+
return Optional.ofNullable(providerName);
112+
}
113+
100114
@Override
101115
public String toString() {
102116
return ToString.builder("AwsSessionCredentials")
103117
.add("accessKeyId", accessKeyId())
118+
.add("providerName", providerName)
104119
.build();
105120
}
106121

@@ -130,15 +145,30 @@ public int hashCode() {
130145
return hashCode;
131146
}
132147

148+
@Override
149+
public Builder toBuilder() {
150+
return builder().accessKeyId(accessKeyId)
151+
.secretAccessKey(secretAccessKey)
152+
.sessionToken(sessionToken)
153+
.expirationTime(expirationTime)
154+
.providerName(providerName);
155+
}
156+
157+
@Override
158+
public AwsSessionCredentials copy(Consumer<? super Builder> modifier) {
159+
return ToCopyableBuilder.super.copy(modifier);
160+
}
161+
133162
/**
134163
* A builder for creating an instance of {@link AwsSessionCredentials}. This can be created with the static
135164
* {@link #builder()} method.
136165
*/
137-
public static final class Builder {
166+
public static final class Builder implements CopyableBuilder<AwsSessionCredentials.Builder, AwsSessionCredentials> {
138167
private String accessKeyId;
139168
private String secretAccessKey;
140169
private String sessionToken;
141170
private Instant expirationTime;
171+
private String providerName;
142172

143173
/**
144174
* The AWS access key, used to identify the user interacting with services. Required.
@@ -175,6 +205,14 @@ public Builder expirationTime(Instant expirationTime) {
175205
return this;
176206
}
177207

208+
/**
209+
* The name of the identity provider that created this credential identity.
210+
*/
211+
public Builder providerName(String providerName) {
212+
this.providerName = providerName;
213+
return this;
214+
}
215+
178216
public AwsSessionCredentials build() {
179217
return new AwsSessionCredentials(this);
180218
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
public final class ContainerCredentialsProvider
7373
implements HttpCredentialsProvider,
7474
ToCopyableBuilder<ContainerCredentialsProvider.Builder, ContainerCredentialsProvider> {
75+
private static final String PROVIDER_NAME = "ContainerCredentialsProvider";
7576
private static final Predicate<InetAddress> IS_LOOPBACK_ADDRESS = InetAddress::isLoopbackAddress;
7677
private static final Predicate<InetAddress> ALLOWED_HOSTS_RULES = IS_LOOPBACK_ADDRESS;
7778
private static final String HTTPS = "https";
@@ -97,7 +98,7 @@ private ContainerCredentialsProvider(BuilderImpl builder) {
9798
this.endpoint = builder.endpoint;
9899
this.asyncCredentialUpdateEnabled = builder.asyncCredentialUpdateEnabled;
99100
this.asyncThreadName = builder.asyncThreadName;
100-
this.httpCredentialsLoader = HttpCredentialsLoader.create();
101+
this.httpCredentialsLoader = HttpCredentialsLoader.create(PROVIDER_NAME);
101102

102103
if (Boolean.TRUE.equals(builder.asyncCredentialUpdateEnabled)) {
103104
Validate.paramNotBlank(builder.asyncThreadName, "asyncThreadName");
@@ -121,7 +122,7 @@ public static Builder builder() {
121122

122123
@Override
123124
public String toString() {
124-
return ToString.create("ContainerCredentialsProvider");
125+
return ToString.create(PROVIDER_NAME);
125126
}
126127

127128
private RefreshResult<AwsCredentials> refreshCredentials() {

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
@SdkPublicApi
2929
public final class EnvironmentVariableCredentialsProvider extends SystemSettingsCredentialsProvider {
3030

31+
private static final String PROVIDER_NAME = "EnvironmentVariableCredentialsProvider";
32+
3133
private EnvironmentVariableCredentialsProvider() {
3234
}
3335

@@ -43,8 +45,13 @@ protected Optional<String> loadSetting(SystemSetting setting) {
4345
// CHECKSTYLE:ON
4446
}
4547

48+
@Override
49+
protected String provider() {
50+
return PROVIDER_NAME;
51+
}
52+
4653
@Override
4754
public String toString() {
48-
return ToString.create("EnvironmentVariableCredentialsProvider");
55+
return ToString.create(PROVIDER_NAME);
4956
}
5057
}

0 commit comments

Comments
 (0)