• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 package software.amazon.awssdk.services.sts.auth;
17 
18 import static software.amazon.awssdk.services.sts.internal.StsAuthUtils.toAwsSessionCredentials;
19 import static software.amazon.awssdk.utils.Validate.notNull;
20 
21 import java.util.function.Consumer;
22 import java.util.function.Supplier;
23 import software.amazon.awssdk.annotations.NotThreadSafe;
24 import software.amazon.awssdk.annotations.SdkPublicApi;
25 import software.amazon.awssdk.annotations.ThreadSafe;
26 import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
27 import software.amazon.awssdk.auth.credentials.AwsSessionCredentials;
28 import software.amazon.awssdk.services.sts.StsClient;
29 import software.amazon.awssdk.services.sts.model.AssumeRoleWithWebIdentityRequest;
30 import software.amazon.awssdk.utils.ToString;
31 import software.amazon.awssdk.utils.builder.ToCopyableBuilder;
32 
33 /**
34  * An implementation of {@link AwsCredentialsProvider} that periodically sends an {@link AssumeRoleWithWebIdentityRequest} to the
35  * AWS Security Token Service to maintain short-lived sessions to use for authentication. These sessions are updated using a
36  * single calling thread (by default) or asynchronously (if {@link Builder#asyncCredentialUpdateEnabled(Boolean)} is set).
37  *
38  * If the credentials are not successfully updated before expiration, calls to {@link #resolveCredentials()} will block until
39  * they are updated successfully.
40  *
41  * Users of this provider must {@link #close()} it when they are finished using it.
42  *
43  * This is created using {@link #builder()}.
44  */
45 @SdkPublicApi
46 @ThreadSafe
47 public final class StsAssumeRoleWithWebIdentityCredentialsProvider
48     extends StsCredentialsProvider
49     implements ToCopyableBuilder<StsAssumeRoleWithWebIdentityCredentialsProvider.Builder,
50                                  StsAssumeRoleWithWebIdentityCredentialsProvider> {
51     private final Supplier<AssumeRoleWithWebIdentityRequest> assumeRoleWithWebIdentityRequest;
52 
53     /**
54      * @see #builder()
55      */
StsAssumeRoleWithWebIdentityCredentialsProvider(Builder builder)56     private StsAssumeRoleWithWebIdentityCredentialsProvider(Builder builder) {
57         super(builder, "sts-assume-role-with-web-identity-credentials-provider");
58         notNull(builder.assumeRoleWithWebIdentityRequestSupplier, "Assume role with web identity request must not be null.");
59 
60         this.assumeRoleWithWebIdentityRequest = builder.assumeRoleWithWebIdentityRequestSupplier;
61     }
62 
63     /**
64      * Create a builder for an {@link StsAssumeRoleWithWebIdentityCredentialsProvider}.
65      */
builder()66     public static Builder builder() {
67         return new Builder();
68     }
69 
70     @Override
getUpdatedCredentials(StsClient stsClient)71     protected AwsSessionCredentials getUpdatedCredentials(StsClient stsClient) {
72         AssumeRoleWithWebIdentityRequest request = assumeRoleWithWebIdentityRequest.get();
73         notNull(request, "AssumeRoleWithWebIdentityRequest can't be null");
74         return toAwsSessionCredentials(stsClient.assumeRoleWithWebIdentity(request).credentials());
75     }
76 
77     @Override
toString()78     public String toString() {
79         return ToString.create("StsAssumeRoleWithWebIdentityCredentialsProvider");
80     }
81 
82     @Override
toBuilder()83     public Builder toBuilder() {
84         return new Builder(this);
85     }
86 
87     /**
88      * A builder (created by {@link StsAssumeRoleWithWebIdentityCredentialsProvider#builder()}) for creating a
89      * {@link StsAssumeRoleWithWebIdentityCredentialsProvider}.
90      */
91     @NotThreadSafe
92     public static final class Builder extends BaseBuilder<Builder, StsAssumeRoleWithWebIdentityCredentialsProvider> {
93         private Supplier<AssumeRoleWithWebIdentityRequest> assumeRoleWithWebIdentityRequestSupplier;
94 
Builder()95         private Builder() {
96             super(StsAssumeRoleWithWebIdentityCredentialsProvider::new);
97         }
98 
Builder(StsAssumeRoleWithWebIdentityCredentialsProvider provider)99         public Builder(StsAssumeRoleWithWebIdentityCredentialsProvider provider) {
100             super(StsAssumeRoleWithWebIdentityCredentialsProvider::new, provider);
101             this.assumeRoleWithWebIdentityRequestSupplier = provider.assumeRoleWithWebIdentityRequest;
102         }
103 
104         /**
105          * Configure the {@link AssumeRoleWithWebIdentityRequest} that should be periodically sent to the STS service to update
106          * the session token when it gets close to expiring.
107          *
108          * @param assumeRoleWithWebIdentityRequest The request to send to STS whenever the assumed session expires.
109          * @return This object for chained calls.
110          */
refreshRequest(AssumeRoleWithWebIdentityRequest assumeRoleWithWebIdentityRequest)111         public Builder refreshRequest(AssumeRoleWithWebIdentityRequest assumeRoleWithWebIdentityRequest) {
112             return refreshRequest(() -> assumeRoleWithWebIdentityRequest);
113         }
114 
115         /**
116          * Similar to {@link #refreshRequest(AssumeRoleWithWebIdentityRequest)}, but takes a {@link Supplier} to supply the
117          * request to STS.
118          *
119          * @param assumeRoleWithWebIdentityRequest A supplier
120          * @return This object for chained calls.
121          */
refreshRequest(Supplier<AssumeRoleWithWebIdentityRequest> assumeRoleWithWebIdentityRequest)122         public Builder refreshRequest(Supplier<AssumeRoleWithWebIdentityRequest> assumeRoleWithWebIdentityRequest) {
123             this.assumeRoleWithWebIdentityRequestSupplier = assumeRoleWithWebIdentityRequest;
124             return this;
125         }
126 
127         /**
128          * Similar to {@link #refreshRequest(AssumeRoleWithWebIdentityRequest)}, but takes a lambda to configure a new
129          * {@link AssumeRoleWithWebIdentityRequest.Builder}. This removes the need to called
130          * {@link AssumeRoleWithWebIdentityRequest#builder()} and {@link AssumeRoleWithWebIdentityRequest.Builder#build()}.
131          */
refreshRequest(Consumer<AssumeRoleWithWebIdentityRequest.Builder> assumeRoleWithWebIdentityRequest)132         public Builder refreshRequest(Consumer<AssumeRoleWithWebIdentityRequest.Builder> assumeRoleWithWebIdentityRequest) {
133             return refreshRequest(AssumeRoleWithWebIdentityRequest.builder().applyMutation(assumeRoleWithWebIdentityRequest)
134                                                                   .build());
135         }
136 
137         @Override
build()138         public StsAssumeRoleWithWebIdentityCredentialsProvider build() {
139             return super.build();
140         }
141     }
142 }
143