• 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 
20 import java.util.function.Consumer;
21 import java.util.function.Supplier;
22 import software.amazon.awssdk.annotations.NotThreadSafe;
23 import software.amazon.awssdk.annotations.SdkPublicApi;
24 import software.amazon.awssdk.annotations.ThreadSafe;
25 import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
26 import software.amazon.awssdk.auth.credentials.AwsSessionCredentials;
27 import software.amazon.awssdk.services.sts.StsClient;
28 import software.amazon.awssdk.services.sts.model.AssumeRoleRequest;
29 import software.amazon.awssdk.utils.ToString;
30 import software.amazon.awssdk.utils.Validate;
31 import software.amazon.awssdk.utils.builder.ToCopyableBuilder;
32 
33 /**
34  * An implementation of {@link AwsCredentialsProvider} that periodically sends an {@link AssumeRoleRequest} to the AWS
35  * Security Token Service to maintain short-lived sessions to use for authentication. These sessions are updated using a single
36  * 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 StsAssumeRoleCredentialsProvider#builder()}.
44  */
45 @SdkPublicApi
46 @ThreadSafe
47 public final class StsAssumeRoleCredentialsProvider
48     extends StsCredentialsProvider
49     implements ToCopyableBuilder<StsAssumeRoleCredentialsProvider.Builder, StsAssumeRoleCredentialsProvider> {
50     private Supplier<AssumeRoleRequest> assumeRoleRequestSupplier;
51 
52     /**
53      * @see #builder()
54      */
StsAssumeRoleCredentialsProvider(Builder builder)55     private StsAssumeRoleCredentialsProvider(Builder builder) {
56         super(builder, "sts-assume-role-credentials-provider");
57         Validate.notNull(builder.assumeRoleRequestSupplier, "Assume role request must not be null.");
58 
59         this.assumeRoleRequestSupplier = builder.assumeRoleRequestSupplier;
60     }
61 
62     /**
63      * Create a builder for an {@link StsAssumeRoleCredentialsProvider}.
64      */
builder()65     public static Builder builder() {
66         return new Builder();
67     }
68 
69     @Override
getUpdatedCredentials(StsClient stsClient)70     protected AwsSessionCredentials getUpdatedCredentials(StsClient stsClient) {
71         AssumeRoleRequest assumeRoleRequest = assumeRoleRequestSupplier.get();
72         Validate.notNull(assumeRoleRequest, "Assume role request must not be null.");
73         return toAwsSessionCredentials(stsClient.assumeRole(assumeRoleRequest).credentials());
74     }
75 
76     @Override
toString()77     public String toString() {
78         return ToString.create("StsAssumeRoleCredentialsProvider");
79     }
80 
81     @Override
toBuilder()82     public Builder toBuilder() {
83         return new Builder(this);
84     }
85 
86     /**
87      * A builder (created by {@link StsAssumeRoleCredentialsProvider#builder()}) for creating a
88      * {@link StsAssumeRoleCredentialsProvider}.
89      */
90     @NotThreadSafe
91     public static final class Builder extends BaseBuilder<Builder, StsAssumeRoleCredentialsProvider> {
92         private Supplier<AssumeRoleRequest> assumeRoleRequestSupplier;
93 
Builder()94         private Builder() {
95             super(StsAssumeRoleCredentialsProvider::new);
96         }
97 
Builder(StsAssumeRoleCredentialsProvider provider)98         private Builder(StsAssumeRoleCredentialsProvider provider) {
99             super(StsAssumeRoleCredentialsProvider::new, provider);
100             this.assumeRoleRequestSupplier = provider.assumeRoleRequestSupplier;
101         }
102 
103         /**
104          * Configure the {@link AssumeRoleRequest} that should be periodically sent to the STS service to update the assumed
105          * credentials.
106          *
107          * @param assumeRoleRequest The request to send to STS whenever the assumed session expires.
108          * @return This object for chained calls.
109          */
refreshRequest(AssumeRoleRequest assumeRoleRequest)110         public Builder refreshRequest(AssumeRoleRequest assumeRoleRequest) {
111             return refreshRequest(() -> assumeRoleRequest);
112         }
113 
114         /**
115          * Similar to {@link #refreshRequest(AssumeRoleRequest)}, but takes a {@link Supplier} to supply the request to
116          * STS.
117          *
118          * @param assumeRoleRequestSupplier A supplier
119          * @return This object for chained calls.
120          */
refreshRequest(Supplier<AssumeRoleRequest> assumeRoleRequestSupplier)121         public Builder refreshRequest(Supplier<AssumeRoleRequest> assumeRoleRequestSupplier) {
122             this.assumeRoleRequestSupplier = assumeRoleRequestSupplier;
123             return this;
124         }
125 
126         /**
127          * Similar to {@link #refreshRequest(AssumeRoleRequest)}, but takes a lambda to configure a new
128          * {@link AssumeRoleRequest.Builder}. This removes the need to called {@link AssumeRoleRequest#builder()} and
129          * {@link AssumeRoleRequest.Builder#build()}.
130          */
refreshRequest(Consumer<AssumeRoleRequest.Builder> assumeRoleRequest)131         public Builder refreshRequest(Consumer<AssumeRoleRequest.Builder> assumeRoleRequest) {
132             return refreshRequest(AssumeRoleRequest.builder().applyMutation(assumeRoleRequest).build());
133         }
134 
135         @Override
build()136         public StsAssumeRoleCredentialsProvider build() {
137             return super.build();
138         }
139 
140     }
141 }
142