• 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.auth.credentials;
17 
18 import java.util.Optional;
19 import java.util.function.Supplier;
20 import software.amazon.awssdk.annotations.SdkPublicApi;
21 import software.amazon.awssdk.auth.credentials.internal.LazyAwsCredentialsProvider;
22 import software.amazon.awssdk.profiles.ProfileFile;
23 import software.amazon.awssdk.profiles.ProfileFileSupplier;
24 import software.amazon.awssdk.utils.SdkAutoCloseable;
25 import software.amazon.awssdk.utils.ToString;
26 import software.amazon.awssdk.utils.builder.CopyableBuilder;
27 import software.amazon.awssdk.utils.builder.ToCopyableBuilder;
28 
29 /**
30  * AWS credentials provider chain that looks for credentials in this order:
31  * <ol>
32  *   <li>Java System Properties - {@code aws.accessKeyId} and {@code aws.secretAccessKey}</li>
33  *   <li>Environment Variables - {@code AWS_ACCESS_KEY_ID} and {@code AWS_SECRET_ACCESS_KEY}</li>
34  *   <li>Web Identity Token credentials from system properties or environment variables</li>
35  *   <li>Credential profiles file at the default location (~/.aws/credentials) shared by all AWS SDKs and the AWS CLI</li>
36  *   <li>Credentials delivered through the Amazon EC2 container service if AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" environment
37  *   variable is set and security manager has permission to access the variable,</li>
38  *   <li>Instance profile credentials delivered through the Amazon EC2 metadata service</li>
39  * </ol>
40  *
41  * @see SystemPropertyCredentialsProvider
42  * @see EnvironmentVariableCredentialsProvider
43  * @see ProfileCredentialsProvider
44  * @see WebIdentityTokenFileCredentialsProvider
45  * @see ContainerCredentialsProvider
46  * @see InstanceProfileCredentialsProvider
47  */
48 @SdkPublicApi
49 public final class DefaultCredentialsProvider
50     implements AwsCredentialsProvider, SdkAutoCloseable,
51                ToCopyableBuilder<DefaultCredentialsProvider.Builder, DefaultCredentialsProvider> {
52 
53     private static final DefaultCredentialsProvider DEFAULT_CREDENTIALS_PROVIDER = new DefaultCredentialsProvider(builder());
54 
55     private final LazyAwsCredentialsProvider providerChain;
56 
57     private final Supplier<ProfileFile> profileFile;
58 
59     private final String profileName;
60 
61     private final Boolean reuseLastProviderEnabled;
62 
63     private final Boolean asyncCredentialUpdateEnabled;
64 
65     /**
66      * @see #builder()
67      */
DefaultCredentialsProvider(Builder builder)68     private DefaultCredentialsProvider(Builder builder) {
69         this.profileFile = builder.profileFile;
70         this.profileName = builder.profileName;
71         this.reuseLastProviderEnabled = builder.reuseLastProviderEnabled;
72         this.asyncCredentialUpdateEnabled = builder.asyncCredentialUpdateEnabled;
73         this.providerChain = createChain(builder);
74     }
75 
76     /**
77      * Create an instance of the {@link DefaultCredentialsProvider} using the default configuration. Configuration can be
78      * specified by creating an instance using the {@link #builder()}.
79      */
create()80     public static DefaultCredentialsProvider create() {
81         return DEFAULT_CREDENTIALS_PROVIDER;
82     }
83 
84     /**
85      * Create the default credential chain using the configuration in the provided builder.
86      */
createChain(Builder builder)87     private static LazyAwsCredentialsProvider createChain(Builder builder) {
88         boolean asyncCredentialUpdateEnabled = builder.asyncCredentialUpdateEnabled;
89         boolean reuseLastProviderEnabled = builder.reuseLastProviderEnabled;
90 
91         return LazyAwsCredentialsProvider.create(() -> {
92             AwsCredentialsProvider[] credentialsProviders = new AwsCredentialsProvider[] {
93                 SystemPropertyCredentialsProvider.create(),
94                 EnvironmentVariableCredentialsProvider.create(),
95                 WebIdentityTokenFileCredentialsProvider.builder()
96                                                        .asyncCredentialUpdateEnabled(asyncCredentialUpdateEnabled)
97                                                        .build(),
98                 ProfileCredentialsProvider.builder()
99                                           .profileFile(builder.profileFile)
100                                           .profileName(builder.profileName)
101                                           .build(),
102                 ContainerCredentialsProvider.builder()
103                                             .asyncCredentialUpdateEnabled(asyncCredentialUpdateEnabled)
104                                             .build(),
105                 InstanceProfileCredentialsProvider.builder()
106                                                   .asyncCredentialUpdateEnabled(asyncCredentialUpdateEnabled)
107                                                   .profileFile(builder.profileFile)
108                                                   .profileName(builder.profileName)
109                                                   .build()
110             };
111 
112             return AwsCredentialsProviderChain.builder()
113                                               .reuseLastProviderEnabled(reuseLastProviderEnabled)
114                                               .credentialsProviders(credentialsProviders)
115                                               .build();
116         });
117     }
118 
119     /**
120      * Get a builder for defining a {@link DefaultCredentialsProvider} with custom configuration.
121      */
builder()122     public static Builder builder() {
123         return new Builder();
124     }
125 
126     @Override
resolveCredentials()127     public AwsCredentials resolveCredentials() {
128         return providerChain.resolveCredentials();
129     }
130 
131     @Override
close()132     public void close() {
133         providerChain.close();
134     }
135 
136     @Override
toString()137     public String toString() {
138         return ToString.builder("DefaultCredentialsProvider")
139                        .add("providerChain", providerChain)
140                        .build();
141     }
142 
143     @Override
toBuilder()144     public Builder toBuilder() {
145         return new Builder(this);
146     }
147 
148     /**
149      * Configuration that defines the {@link DefaultCredentialsProvider}'s behavior.
150      */
151     public static final class Builder implements CopyableBuilder<Builder, DefaultCredentialsProvider> {
152         private Supplier<ProfileFile> profileFile;
153         private String profileName;
154         private Boolean reuseLastProviderEnabled = true;
155         private Boolean asyncCredentialUpdateEnabled = false;
156 
157         /**
158          * Created with {@link #builder()}.
159          */
Builder()160         private Builder() {
161         }
162 
Builder(DefaultCredentialsProvider credentialsProvider)163         private Builder(DefaultCredentialsProvider credentialsProvider) {
164             this.profileFile = credentialsProvider.profileFile;
165             this.profileName = credentialsProvider.profileName;
166             this.reuseLastProviderEnabled = credentialsProvider.reuseLastProviderEnabled;
167             this.asyncCredentialUpdateEnabled = credentialsProvider.asyncCredentialUpdateEnabled;
168         }
169 
profileFile(ProfileFile profileFile)170         public Builder profileFile(ProfileFile profileFile) {
171             return profileFile(Optional.ofNullable(profileFile)
172                                        .map(ProfileFileSupplier::fixedProfileFile)
173                                        .orElse(null));
174         }
175 
profileFile(Supplier<ProfileFile> profileFileSupplier)176         public Builder profileFile(Supplier<ProfileFile> profileFileSupplier) {
177             this.profileFile = profileFileSupplier;
178             return this;
179         }
180 
profileName(String profileName)181         public Builder profileName(String profileName) {
182             this.profileName = profileName;
183             return this;
184         }
185 
186         /**
187          * Controls whether the provider should reuse the last successful credentials provider in the chain. Reusing the last
188          * successful credentials provider will typically return credentials faster than searching through the chain.
189          *
190          * <p>By default, this is enabled.</p>
191          */
reuseLastProviderEnabled(Boolean reuseLastProviderEnabled)192         public Builder reuseLastProviderEnabled(Boolean reuseLastProviderEnabled) {
193             this.reuseLastProviderEnabled = reuseLastProviderEnabled;
194             return this;
195         }
196 
197         /**
198          * Configure whether this provider should fetch credentials asynchronously in the background. If this is true, threads are
199          * less likely to block when {@link #resolveCredentials()} is called, but additional resources are used to maintain the
200          * provider.
201          *
202          * <p>By default, this is disabled.</p>
203          */
asyncCredentialUpdateEnabled(Boolean asyncCredentialUpdateEnabled)204         public Builder asyncCredentialUpdateEnabled(Boolean asyncCredentialUpdateEnabled) {
205             this.asyncCredentialUpdateEnabled = asyncCredentialUpdateEnabled;
206             return this;
207         }
208 
209         /**
210          * Create a {@link DefaultCredentialsProvider} using the configuration defined in this builder.
211          */
212         @Override
build()213         public DefaultCredentialsProvider build() {
214             return new DefaultCredentialsProvider(this);
215         }
216     }
217 }
218