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 default, this 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 default, this 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