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.services.sts.auth; 17 18 import static software.amazon.awssdk.services.sts.internal.StsAuthUtils.toAwsSessionCredentials; 19 20 import java.util.function.Consumer; 21 import software.amazon.awssdk.annotations.NotThreadSafe; 22 import software.amazon.awssdk.annotations.SdkPublicApi; 23 import software.amazon.awssdk.annotations.ThreadSafe; 24 import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; 25 import software.amazon.awssdk.auth.credentials.AwsSessionCredentials; 26 import software.amazon.awssdk.services.sts.StsClient; 27 import software.amazon.awssdk.services.sts.model.GetSessionTokenRequest; 28 import software.amazon.awssdk.utils.ToString; 29 import software.amazon.awssdk.utils.Validate; 30 import software.amazon.awssdk.utils.builder.ToCopyableBuilder; 31 32 /** 33 * An implementation of {@link AwsCredentialsProvider} that periodically sends a {@link GetSessionTokenRequest} to the AWS 34 * Security Token Service to maintain short-lived sessions to use for authentication. These sessions are updated using a single 35 * calling thread (by default) or asynchronously (if {@link Builder#asyncCredentialUpdateEnabled(Boolean)} is set). 36 * 37 * If the credentials are not successfully updated before expiration, calls to {@link #resolveCredentials()} will block until 38 * they are updated successfully. 39 * 40 * Users of this provider must {@link #close()} it when they are finished using it. 41 * 42 * This is created using {@link #builder()}. 43 */ 44 @SdkPublicApi 45 @ThreadSafe 46 public class StsGetSessionTokenCredentialsProvider 47 extends StsCredentialsProvider 48 implements ToCopyableBuilder<StsGetSessionTokenCredentialsProvider.Builder, StsGetSessionTokenCredentialsProvider> { 49 private final GetSessionTokenRequest getSessionTokenRequest; 50 51 /** 52 * @see #builder() 53 */ StsGetSessionTokenCredentialsProvider(Builder builder)54 private StsGetSessionTokenCredentialsProvider(Builder builder) { 55 super(builder, "sts-get-token-credentials-provider"); 56 Validate.notNull(builder.getSessionTokenRequest, "Get session token request must not be null."); 57 58 this.getSessionTokenRequest = builder.getSessionTokenRequest; 59 } 60 61 /** 62 * Create a builder for an {@link StsGetSessionTokenCredentialsProvider}. 63 */ builder()64 public static Builder builder() { 65 return new Builder(); 66 } 67 68 @Override getUpdatedCredentials(StsClient stsClient)69 protected AwsSessionCredentials getUpdatedCredentials(StsClient stsClient) { 70 return toAwsSessionCredentials(stsClient.getSessionToken(getSessionTokenRequest).credentials()); 71 } 72 73 @Override toString()74 public String toString() { 75 return ToString.create("StsGetSessionTokenCredentialsProvider"); 76 } 77 78 @Override toBuilder()79 public Builder toBuilder() { 80 return new Builder(this); 81 } 82 83 /** 84 * A builder (created by {@link StsGetSessionTokenCredentialsProvider#builder()}) for creating a 85 * {@link StsGetSessionTokenCredentialsProvider}. 86 */ 87 @NotThreadSafe 88 public static final class Builder extends BaseBuilder<Builder, StsGetSessionTokenCredentialsProvider> { 89 private GetSessionTokenRequest getSessionTokenRequest = GetSessionTokenRequest.builder().build(); 90 Builder()91 private Builder() { 92 super(StsGetSessionTokenCredentialsProvider::new); 93 } 94 Builder(StsGetSessionTokenCredentialsProvider provider)95 public Builder(StsGetSessionTokenCredentialsProvider provider) { 96 super(StsGetSessionTokenCredentialsProvider::new, provider); 97 this.getSessionTokenRequest = provider.getSessionTokenRequest; 98 } 99 100 /** 101 * Configure the {@link GetSessionTokenRequest} that should be periodically sent to the STS service to update the session 102 * token when it gets close to expiring. 103 * 104 * If this is not specified, default values are used. 105 * 106 * @param getSessionTokenRequest The request to send to STS whenever the assumed session expires. 107 * @return This object for chained calls. 108 */ refreshRequest(GetSessionTokenRequest getSessionTokenRequest)109 public Builder refreshRequest(GetSessionTokenRequest getSessionTokenRequest) { 110 this.getSessionTokenRequest = getSessionTokenRequest; 111 return this; 112 } 113 114 /** 115 * Similar to {@link #refreshRequest(GetSessionTokenRequest)}, but takes a lambda to configure a new 116 * {@link GetSessionTokenRequest.Builder}. This removes the need to called 117 * {@link GetSessionTokenRequest#builder()} and {@link GetSessionTokenRequest.Builder#build()}. 118 */ refreshRequest(Consumer<GetSessionTokenRequest.Builder> getFederationTokenRequest)119 public Builder refreshRequest(Consumer<GetSessionTokenRequest.Builder> getFederationTokenRequest) { 120 return refreshRequest(GetSessionTokenRequest.builder().applyMutation(getFederationTokenRequest).build()); 121 } 122 123 @Override build()124 public StsGetSessionTokenCredentialsProvider build() { 125 return super.build(); 126 } 127 } 128 } 129