All Downloads are FREE. Search and download functionalities are using the official Maven repository.

software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain Maven / Gradle / Ivy

Go to download

The AWS SDK for Java - Auth module holds the classes that are used for authentication with services

There is a newer version: 2.29.15
Show newest version
/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

package software.amazon.awssdk.auth.credentials;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import software.amazon.awssdk.annotations.SdkPublicApi;
import software.amazon.awssdk.core.exception.SdkClientException;
import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.utils.CompletableFutureUtils;
import software.amazon.awssdk.utils.IoUtils;
import software.amazon.awssdk.utils.Logger;
import software.amazon.awssdk.utils.SdkAutoCloseable;
import software.amazon.awssdk.utils.ToString;
import software.amazon.awssdk.utils.Validate;
import software.amazon.awssdk.utils.builder.CopyableBuilder;
import software.amazon.awssdk.utils.builder.ToCopyableBuilder;

/**
 * {@link AwsCredentialsProvider} implementation that chains together multiple credentials providers.
 *
 * 

When a caller first requests credentials from this provider, it calls all the providers in the chain, in the original order * specified, until one can provide credentials, and then returns those credentials. If all of the credential providers in the * chain have been called, and none of them can provide credentials, then this class will throw an exception indicated that no * credentials are available.

* *

By default, this class will remember the first credentials provider in the chain that was able to provide credentials, and * will continue to use that provider when credentials are requested in the future, instead of traversing the chain each time. * This behavior can be controlled through the {@link Builder#reuseLastProviderEnabled(Boolean)} method.

* *

This chain implements {@link AutoCloseable}. When closed, it will call the {@link AutoCloseable#close()} on any credential * providers in the chain that need to be closed.

*/ @SdkPublicApi public final class AwsCredentialsProviderChain implements AwsCredentialsProvider, SdkAutoCloseable, ToCopyableBuilder { private static final Logger log = Logger.loggerFor(AwsCredentialsProviderChain.class); private final List> credentialsProviders; private final boolean reuseLastProviderEnabled; private volatile IdentityProvider lastUsedProvider; /** * @see #builder() */ private AwsCredentialsProviderChain(BuilderImpl builder) { Validate.notEmpty(builder.credentialsProviders, "No credential providers were specified."); this.reuseLastProviderEnabled = builder.reuseLastProviderEnabled; this.credentialsProviders = Collections.unmodifiableList(builder.credentialsProviders); } /** * Get a new builder for creating a {@link AwsCredentialsProviderChain}. */ public static Builder builder() { return new BuilderImpl(); } /** * Create an AWS credentials provider chain with default configuration that checks the given credential providers. * @param awsCredentialsProviders The credentials providers that should be checked for credentials, in the order they should * be checked. * @return A credential provider chain that checks the provided credential providers in order. */ public static AwsCredentialsProviderChain of(AwsCredentialsProvider... awsCredentialsProviders) { return builder().credentialsProviders(awsCredentialsProviders).build(); } /** * Create an AWS credentials provider chain with default configuration that checks the given credential providers. * @param awsCredentialsProviders The credentials providers that should be checked for credentials, in the order they should * be checked. * @return A credential provider chain that checks the provided credential providers in order. */ public static AwsCredentialsProviderChain of(IdentityProvider... awsCredentialsProviders) { return builder().credentialsProviders(awsCredentialsProviders).build(); } @Override public AwsCredentials resolveCredentials() { if (reuseLastProviderEnabled && lastUsedProvider != null) { return CredentialUtils.toCredentials(CompletableFutureUtils.joinLikeSync(lastUsedProvider.resolveIdentity())); } List exceptionMessages = null; for (IdentityProvider provider : credentialsProviders) { try { AwsCredentialsIdentity credentials = CompletableFutureUtils.joinLikeSync(provider.resolveIdentity()); log.debug(() -> "Loading credentials from " + provider); lastUsedProvider = provider; return CredentialUtils.toCredentials(credentials); } catch (RuntimeException e) { // Ignore any exceptions and move onto the next provider String message = provider + ": " + e.getMessage(); log.debug(() -> "Unable to load credentials from " + message , e); if (exceptionMessages == null) { exceptionMessages = new ArrayList<>(); } exceptionMessages.add(message); } } throw SdkClientException.builder() .message("Unable to load credentials from any of the providers in the chain " + this + " : " + exceptionMessages) .build(); } @Override public void close() { credentialsProviders.forEach(c -> IoUtils.closeIfCloseable(c, null)); } @Override public String toString() { return ToString.builder("AwsCredentialsProviderChain") .add("credentialsProviders", credentialsProviders) .build(); } @Override public Builder toBuilder() { return new BuilderImpl(this); } /** * A builder for a {@link AwsCredentialsProviderChain} that allows controlling its behavior. */ public interface Builder extends CopyableBuilder { /** * Controls whether the chain should reuse the last successful credentials provider in the chain. Reusing the last * successful credentials provider will typically return credentials faster than searching through the chain. * *

* By default, this is enabled */ Builder reuseLastProviderEnabled(Boolean reuseLastProviderEnabled); /** * Configure the credentials providers that should be checked for credentials, in the order they should be checked. */ Builder credentialsProviders(Collection credentialsProviders); /** * Configure the credentials providers that should be checked for credentials, in the order they should be checked. */ Builder credentialsIdentityProviders( Collection> credentialsProviders); /** * Configure the credentials providers that should be checked for credentials, in the order they should be checked. */ default Builder credentialsProviders(AwsCredentialsProvider... credentialsProviders) { return credentialsProviders((IdentityProvider[]) credentialsProviders); } /** * Configure the credentials providers that should be checked for credentials, in the order they should be checked. */ default Builder credentialsProviders(IdentityProvider... credentialsProviders) { throw new UnsupportedOperationException(); } /** * Add a credential provider to the chain, after the credential providers that have already been configured. */ default Builder addCredentialsProvider(AwsCredentialsProvider credentialsProvider) { return addCredentialsProvider((IdentityProvider) credentialsProvider); } /** * Add a credential provider to the chain, after the credential providers that have already been configured. */ default Builder addCredentialsProvider(IdentityProvider credentialsProvider) { throw new UnsupportedOperationException(); } AwsCredentialsProviderChain build(); } private static final class BuilderImpl implements Builder { private Boolean reuseLastProviderEnabled = true; private List> credentialsProviders = new ArrayList<>(); private BuilderImpl() { } private BuilderImpl(AwsCredentialsProviderChain provider) { this.reuseLastProviderEnabled = provider.reuseLastProviderEnabled; this.credentialsProviders = provider.credentialsProviders; } @Override public Builder reuseLastProviderEnabled(Boolean reuseLastProviderEnabled) { this.reuseLastProviderEnabled = reuseLastProviderEnabled; return this; } public void setReuseLastProviderEnabled(Boolean reuseLastProviderEnabled) { reuseLastProviderEnabled(reuseLastProviderEnabled); } @Override public Builder credentialsProviders(Collection credentialsProviders) { this.credentialsProviders = new ArrayList<>(credentialsProviders); return this; } public void setCredentialsProviders(Collection credentialsProviders) { credentialsProviders(credentialsProviders); } @Override public Builder credentialsIdentityProviders( Collection> credentialsProviders) { this.credentialsProviders = new ArrayList<>(credentialsProviders); return this; } public void setCredentialsIdentityProviders( Collection> credentialsProviders) { credentialsIdentityProviders(credentialsProviders); } @Override public Builder credentialsProviders(IdentityProvider... credentialsProviders) { return credentialsIdentityProviders(Arrays.asList(credentialsProviders)); } @Override public Builder addCredentialsProvider(IdentityProvider credentialsProvider) { this.credentialsProviders.add(credentialsProvider); return this; } @Override public AwsCredentialsProviderChain build() { return new AwsCredentialsProviderChain(this); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy