1 /*
2  * Copyright 2010-2020 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 package com.amazonaws.auth;
16
17 import com.amazonaws.auth.profile.internal.securitytoken.RoleInfo;
18 import com.amazonaws.auth.profile.internal.securitytoken.STSProfileCredentialsServiceLoader;
19
20 import static com.amazonaws.SDKGlobalConfiguration.AWS_ROLE_ARN_ENV_VAR;
21 import static com.amazonaws.SDKGlobalConfiguration.AWS_ROLE_SESSION_NAME_ENV_VAR;
22 import static com.amazonaws.SDKGlobalConfiguration.AWS_WEB_IDENTITY_ENV_VAR;
23
24 public class WebIdentityTokenCredentialsProvider implements AWSCredentialsProvider {
25
26     private final AWSCredentialsProvider credentialsProvider;
27     private final RuntimeException loadException;
28
29     public WebIdentityTokenCredentialsProvider() {
30         this(new BuilderImpl());
31     }
32
33     private WebIdentityTokenCredentialsProvider(BuilderImpl builder) {
34         AWSCredentialsProvider credentialsProvider = null;
35         RuntimeException loadException = null;
36
37         try {
38             String webIdentityTokenFile =
39                 builder.webIdentityTokenFile != null ? builder.webIdentityTokenFile
40                                                      : System.getenv(AWS_WEB_IDENTITY_ENV_VAR);
41
42             String roleArn = builder.roleArn != null ? builder.roleArn
43                                                      : System.getenv(AWS_ROLE_ARN_ENV_VAR);
44
45             String roleSessionName =
46                 builder.roleSessionName != null ? builder.roleSessionName
47                                                 : System.getenv(AWS_ROLE_SESSION_NAME_ENV_VAR);
48
49             if (roleSessionName == null) {
50                 roleSessionName = "aws-sdk-java-" + System.currentTimeMillis();
51             }
52
53             RoleInfo roleInfo = new RoleInfo()
54                     .withRoleArn(roleArn)
55                     .withRoleSessionName(roleSessionName)
56                     .withWebIdentityTokenFilePath(webIdentityTokenFile);
57
58             credentialsProvider = STSProfileCredentialsServiceLoader.getInstance().getAssumeRoleCredentialsProvider(roleInfo);
59         } catch (RuntimeException e) {
60             // If we couldn't load the credentials provider for some reason, save an exception describing why. This exception
61             // will only be raised on calls to getCredentials. We don't want to raise an exception here because it may be
62             // expected (eg. in the default credential chain).
63             loadException = e;
64         }
65
66         this.loadException = loadException;
67         this.credentialsProvider = credentialsProvider;
68     }
69
70     @Override
71     public AWSCredentials getCredentials() {
72         if (loadException != null) {
73             throw loadException;
74         }
75
76         return credentialsProvider.getCredentials();
77     }
78
79     @Override
80     public void refresh() {
81
82     }
83
84     public static WebIdentityTokenCredentialsProvider create() {
85         return builder().build();
86     }
87
88     public static Builder builder() {
89         return new BuilderImpl();
90     }
91
92     @Override
93     public String toString() {
94         return getClass().getSimpleName();
95     }
96
97     /**
98      * A builder for creating a custom {@link WebIdentityTokenCredentialsProvider}.
99      */

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

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

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

115         Builder webIdentityTokenFile(String webIdentityTokenFile);
116
117         /**
118          * Create a {@link WebIdentityTokenCredentialsProvider} using the configuration applied to this builder.
119          */

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