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 software.amazon.awssdk.annotations.SdkPublicApi;
19 import software.amazon.awssdk.auth.credentials.internal.LazyAwsCredentialsProvider;
20 import software.amazon.awssdk.profiles.ProfileFile;
21 import software.amazon.awssdk.utils.SdkAutoCloseable;
22 import software.amazon.awssdk.utils.ToString;
23
24 /**
25  * AWS credentials provider chain that looks for credentials in this order:
26  * <ol>
27  *   <li>Java System Properties - <code>aws.accessKeyId</code> and <code>aws.secretKey</code></li>
28  *   <li>Environment Variables - <code>AWS_ACCESS_KEY_ID</code> and <code>AWS_SECRET_ACCESS_KEY</code></li>
29  *   <li>Credential profiles file at the default location (~/.aws/credentials) shared by all AWS SDKs and the AWS CLI</li>
30  *   <li>Credentials delivered through the Amazon EC2 container service if AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" environment
31  *   variable is set and security manager has permission to access the variable,</li>
32  *   <li>Instance profile credentials delivered through the Amazon EC2 metadata service</li>
33  * </ol>
34  *
35  * @see SystemPropertyCredentialsProvider
36  * @see EnvironmentVariableCredentialsProvider
37  * @see ProfileCredentialsProvider
38  * @see WebIdentityTokenFileCredentialsProvider
39  * @see ContainerCredentialsProvider
40  * @see InstanceProfileCredentialsProvider
41  */

42 @SdkPublicApi
43 public final class DefaultCredentialsProvider implements AwsCredentialsProvider, SdkAutoCloseable {
44
45     private static final DefaultCredentialsProvider DEFAULT_CREDENTIALS_PROVIDER = new DefaultCredentialsProvider(builder());
46
47     private final LazyAwsCredentialsProvider providerChain;
48
49     /**
50      * @see #builder()
51      */

52     private DefaultCredentialsProvider(Builder builder) {
53         this.providerChain = createChain(builder);
54     }
55
56     /**
57      * Create an create of the {@link DefaultCredentialsProvider} using the default configuration. Configuration can be
58      * specified by creating an create using the {@link #builder()}.
59      */

60     public static DefaultCredentialsProvider create() {
61         return DEFAULT_CREDENTIALS_PROVIDER;
62     }
63
64     /**
65      * Create the default credential chain using the configuration in the provided builder.
66      */

67     private static LazyAwsCredentialsProvider createChain(Builder builder) {
68         boolean asyncCredentialUpdateEnabled = builder.asyncCredentialUpdateEnabled;
69         boolean reuseLastProviderEnabled = builder.reuseLastProviderEnabled;
70
71         return LazyAwsCredentialsProvider.create(() -> {
72             AwsCredentialsProvider[] credentialsProviders = new AwsCredentialsProvider[] {
73                     SystemPropertyCredentialsProvider.create(),
74                     EnvironmentVariableCredentialsProvider.create(),
75                     WebIdentityTokenFileCredentialsProvider.create(),
76                     ProfileCredentialsProvider.builder()
77                                               .profileFile(builder.profileFile)
78                                               .profileName(builder.profileName)
79                                               .build(),
80                     ContainerCredentialsProvider.builder()
81                                                 .asyncCredentialUpdateEnabled(asyncCredentialUpdateEnabled)
82                                                 .build(),
83                     InstanceProfileCredentialsProvider.builder()
84                                                       .asyncCredentialUpdateEnabled(asyncCredentialUpdateEnabled)
85                                                       .build()
86             };
87
88             return AwsCredentialsProviderChain.builder()
89                                               .reuseLastProviderEnabled(reuseLastProviderEnabled)
90                                               .credentialsProviders(credentialsProviders)
91                                               .build();
92         });
93     }
94
95     /**
96      * Get a builder for defining a {@link DefaultCredentialsProvider} with custom configuration.
97      */

98     public static Builder builder() {
99         return new Builder();
100     }
101
102     @Override
103     public AwsCredentials resolveCredentials() {
104         return providerChain.resolveCredentials();
105     }
106
107     @Override
108     public void close() {
109         providerChain.close();
110     }
111
112     @Override
113     public String toString() {
114         return ToString.builder("DefaultCredentialsProvider")
115                        .add("providerChain", providerChain)
116                        .build();
117     }
118
119     /**
120      * Configuration that defines the {@link DefaultCredentialsProvider}'s behavior.
121      */

122     public static final class Builder {
123         private ProfileFile profileFile;
124         private String profileName;
125         private Boolean reuseLastProviderEnabled = true;
126         private Boolean asyncCredentialUpdateEnabled = false;
127
128         /**
129          * Created with {@link #builder()}.
130          */

131         private Builder() {
132         }
133
134         public Builder profileFile(ProfileFile profileFile) {
135             this.profileFile = profileFile;
136             return this;
137         }
138
139         public Builder profileName(String profileName) {
140             this.profileName = profileName;
141             return this;
142         }
143
144         /**
145          * Controls whether the provider should reuse the last successful credentials provider in the chain. Reusing the last
146          * successful credentials provider will typically return credentials faster than searching through the chain.
147          *
148          * <p>By defaultthis is enabled.</p>
149          */

150         public Builder reuseLastProviderEnabled(Boolean reuseLastProviderEnabled) {
151             this.reuseLastProviderEnabled = reuseLastProviderEnabled;
152             return this;
153         }
154
155         /**
156          * Configure whether this provider should fetch credentials asynchronously in the background. If this is true, threads are
157          * less likely to block when {@link #resolveCredentials()} is called, but additional resources are used to maintain the
158          * provider.
159          *
160          * <p>By defaultthis is disabled.</p>
161          */

162         public Builder asyncCredentialUpdateEnabled(Boolean asyncCredentialUpdateEnabled) {
163             this.asyncCredentialUpdateEnabled = asyncCredentialUpdateEnabled;
164             return this;
165         }
166
167         /**
168          * Create a {@link DefaultCredentialsProvider} using the configuration defined in this builder.
169          */

170         public DefaultCredentialsProvider build() {
171             return new DefaultCredentialsProvider(this);
172         }
173     }
174 }
175