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 static software.amazon.awssdk.utils.StringUtils.trim;
19
20 import java.nio.file.Path;
21 import java.nio.file.Paths;
22 import java.util.Optional;
23 import software.amazon.awssdk.annotations.SdkPublicApi;
24 import software.amazon.awssdk.auth.credentials.internal.WebIdentityCredentialsUtils;
25 import software.amazon.awssdk.auth.credentials.internal.WebIdentityTokenCredentialProperties;
26 import software.amazon.awssdk.core.SdkSystemSetting;
27 import software.amazon.awssdk.utils.ToString;
28
29 /**
30  * A credential provider that will read web identity token file path, aws role arn
31  * and aws session name from system properties or environment variables for using
32  * web identity token credentials with STS. Use of this credentials provider requires
33  * the 'sts' module to be on the classpath.
34  */

35 @SdkPublicApi
36 public class WebIdentityTokenFileCredentialsProvider implements AwsCredentialsProvider {
37
38     private final AwsCredentialsProvider credentialsProvider;
39     private final RuntimeException loadException;
40
41     private WebIdentityTokenFileCredentialsProvider(BuilderImpl builder) {
42         AwsCredentialsProvider credentialsProvider = null;
43         RuntimeException loadException = null;
44
45         try {
46             Path webIdentityTokenFile =
47                 builder.webIdentityTokenFile != null ? builder.webIdentityTokenFile
48                                                      : Paths.get(trim(SdkSystemSetting.AWS_WEB_IDENTITY_TOKEN_FILE
49                                                                           .getStringValueOrThrow()));
50
51             String roleArn = builder.roleArn != null ? builder.roleArn
52                                                      : trim(SdkSystemSetting.AWS_ROLE_ARN.getStringValueOrThrow());
53
54             Optional<String> roleSessionName =
55                 builder.roleSessionName != null ? Optional.of(builder.roleSessionName)
56                                                 : SdkSystemSetting.AWS_ROLE_SESSION_NAME.getStringValue();
57
58             WebIdentityTokenCredentialProperties credentialProperties =
59                 WebIdentityTokenCredentialProperties.builder()
60                                                     .roleArn(roleArn)
61                                                     .roleSessionName(roleSessionName.orElse(null))
62                                                     .webIdentityTokenFile(webIdentityTokenFile)
63                                                     .build();
64
65             credentialsProvider = WebIdentityCredentialsUtils.factory().create(credentialProperties);
66         } catch (RuntimeException e) {
67             // If we couldn't load the credentials provider for some reason, save an exception describing why. This exception
68             // will only be raised on calls to getCredentials. We don't want to raise an exception here because it may be
69             // expected (eg. in the default credential chain).
70             loadException = e;
71         }
72
73         this.loadException = loadException;
74         this.credentialsProvider = credentialsProvider;
75     }
76
77     public static WebIdentityTokenFileCredentialsProvider create() {
78
79         return WebIdentityTokenFileCredentialsProvider.builder().build();
80     }
81
82     @Override
83     public AwsCredentials resolveCredentials() {
84         if (loadException != null) {
85             throw loadException;
86         }
87         return credentialsProvider.resolveCredentials();
88     }
89
90     public static Builder builder() {
91         return new BuilderImpl();
92     }
93
94     @Override
95     public String toString() {
96         return ToString.create("WebIdentityTokenCredentialsProvider");
97     }
98
99     /**
100      * A builder for creating a custom {@link WebIdentityTokenFileCredentialsProvider}.
101      */

102     public interface Builder {
103
104         /**
105          * Define the role arn that should be used by this credentials provider.
106          */

107         Builder roleArn(String roleArn);
108
109         /**
110          * Define the role session name that should be used by this credentials provider.
111          */

112         Builder roleSessionName(String roleSessionName);
113
114         /**
115          * Define the absolute path to the web identity token file that should be used by this credentials provider.
116          */

117         Builder webIdentityTokenFile(Path webIdentityTokenFile);
118
119         /**
120          * Create a {@link WebIdentityTokenFileCredentialsProvider} using the configuration applied to this builder.
121          */

122         WebIdentityTokenFileCredentialsProvider build();
123     }
124
125     static final class BuilderImpl implements Builder {
126         private String roleArn;
127         private String roleSessionName;
128         private Path webIdentityTokenFile;
129
130         BuilderImpl() {
131         }
132
133         @Override
134         public Builder roleArn(String roleArn) {
135             this.roleArn = roleArn;
136             return this;
137         }
138
139         public void setRoleArn(String roleArn) {
140             roleArn(roleArn);
141         }
142
143         @Override
144         public Builder roleSessionName(String roleSessionName) {
145             this.roleSessionName = roleSessionName;
146             return this;
147         }
148
149         public void setRoleSessionName(String roleSessionName) {
150             roleSessionName(roleSessionName);
151         }
152
153         @Override
154         public Builder webIdentityTokenFile(Path webIdentityTokenFile) {
155             this.webIdentityTokenFile = webIdentityTokenFile;
156             return this;
157         }
158
159         public void setWebIdentityTokenFile(Path webIdentityTokenFile) {
160             webIdentityTokenFile(webIdentityTokenFile);
161         }
162
163         @Override
164         public WebIdentityTokenFileCredentialsProvider build() {
165             return new WebIdentityTokenFileCredentialsProvider(this);
166         }
167     }
168 }
169