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