From ca9928b5c41c974d4547e8e7064c9b2d120a1d18 Mon Sep 17 00:00:00 2001 From: Saranya Somepalli Date: Thu, 30 Apr 2026 11:58:38 -0700 Subject: [PATCH 1/2] Fix EndpointResolutionStage NPE on null port and preserve interceptor-set AWS_CREDENTIALS during auth scheme resolution --- .../identity/AwsIdentityProviderUpdater.java | 27 ++++++++++++++++--- .../stages/AuthSchemeResolutionStage.java | 2 +- .../stages/EndpointResolutionStage.java | 3 ++- .../spi/identity/IdentityProviderUpdater.java | 9 ++++--- 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/identity/AwsIdentityProviderUpdater.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/identity/AwsIdentityProviderUpdater.java index f83b8de84c85..c4b291aa48c9 100644 --- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/identity/AwsIdentityProviderUpdater.java +++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/identity/AwsIdentityProviderUpdater.java @@ -16,14 +16,18 @@ package software.amazon.awssdk.awscore.internal.identity; import software.amazon.awssdk.annotations.SdkInternalApi; +import software.amazon.awssdk.auth.credentials.AwsCredentials; +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.auth.signer.AwsSignerExecutionAttribute; import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration; import software.amazon.awssdk.core.SdkRequest; +import software.amazon.awssdk.core.interceptor.ExecutionAttributes; import software.amazon.awssdk.core.spi.identity.IdentityProviderUpdater; import software.amazon.awssdk.identity.spi.IdentityProviders; /** * AWS implementation of {@link IdentityProviderUpdater} that reads credential overrides - * from {@link AwsRequestOverrideConfiguration}. + * from {@link AwsRequestOverrideConfiguration} and deprecated {@link AwsSignerExecutionAttribute#AWS_CREDENTIALS}. */ @SdkInternalApi public final class AwsIdentityProviderUpdater implements IdentityProviderUpdater { @@ -38,17 +42,32 @@ public static AwsIdentityProviderUpdater create() { } @Override - public IdentityProviders update(SdkRequest request, IdentityProviders base) { + public IdentityProviders update(SdkRequest request, IdentityProviders base, ExecutionAttributes executionAttributes) { if (base == null) { return null; } - return request.overrideConfiguration() + + IdentityProviders updated = request.overrideConfiguration() .filter(c -> c instanceof AwsRequestOverrideConfiguration) .map(c -> (AwsRequestOverrideConfiguration) c) .map(c -> base.copy(b -> { c.credentialsIdentityProvider().ifPresent(b::putIdentityProvider); c.tokenIdentityProvider().ifPresent(b::putIdentityProvider); })) - .orElse(base); + .orElse(null); + + if (updated != null) { + return updated; + } + + // Support deprecated AWS_CREDENTIALS execution attribute for backwards compatibility + // with interceptors that set credentials via AwsSignerExecutionAttribute.AWS_CREDENTIALS + AwsCredentials credentials = executionAttributes.getOptionalAttribute(AwsSignerExecutionAttribute.AWS_CREDENTIALS) + .orElse(null); + if (credentials != null) { + return base.copy(b -> b.putIdentityProvider(StaticCredentialsProvider.create(credentials))); + } + + return base; } } diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AuthSchemeResolutionStage.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AuthSchemeResolutionStage.java index b5f616d54166..b653db4ddd90 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AuthSchemeResolutionStage.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AuthSchemeResolutionStage.java @@ -108,7 +108,7 @@ private IdentityProviders updateIdentityProvidersIfNeeded(ExecutionAttributes ex IdentityProviderUpdater updater = executionAttributes.getAttribute(SdkInternalExecutionAttribute.IDENTITY_PROVIDER_UPDATER); if (updater != null) { - identityProviders = updater.update(request, identityProviders); + identityProviders = updater.update(request, identityProviders, executionAttributes); } return identityProviders; } diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/EndpointResolutionStage.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/EndpointResolutionStage.java index 40c329f01a84..b01dc444fa77 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/EndpointResolutionStage.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/EndpointResolutionStage.java @@ -104,10 +104,11 @@ private static boolean interceptorModifiedEndpoint(SdkHttpFullRequest.Builder re return false; } String requestHost = request.host(); + Integer requestPort = request.port(); return requestHost != null && (!requestHost.equals(preModifyUri.getHost()) || !String.valueOf(request.protocol()).equals(preModifyUri.getScheme()) - || request.port() != preModifyUri.getPort()); + || (requestPort != null && requestPort != preModifyUri.getPort())); } /** diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/spi/identity/IdentityProviderUpdater.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/spi/identity/IdentityProviderUpdater.java index af54e5ef3661..ac5053b4c33a 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/spi/identity/IdentityProviderUpdater.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/spi/identity/IdentityProviderUpdater.java @@ -17,6 +17,7 @@ import software.amazon.awssdk.annotations.SdkProtectedApi; import software.amazon.awssdk.core.SdkRequest; +import software.amazon.awssdk.core.interceptor.ExecutionAttributes; import software.amazon.awssdk.identity.spi.IdentityProviders; /** @@ -29,11 +30,13 @@ @SdkProtectedApi public interface IdentityProviderUpdater { /** - * Updates identity providers based on request-level overrides. + * Updates identity providers by applying request-level credential overrides or + * credentials set via {@code AwsSignerExecutionAttribute.AWS_CREDENTIALS} by interceptors. * * @param request The request (after interceptors have modified it) * @param base The base identity providers from client configuration - * @return Updated identity providers, or base if no overrides + * @param executionAttributes The execution attributes, checked for interceptor-set AWS_CREDENTIALS + * @return Updated identity providers, or base if no overrides apply */ - IdentityProviders update(SdkRequest request, IdentityProviders base); + IdentityProviders update(SdkRequest request, IdentityProviders base, ExecutionAttributes executionAttributes); } From dedfa392debd5c728babd57d5ce2301d886992ab Mon Sep 17 00:00:00 2001 From: Saranya Somepalli Date: Thu, 30 Apr 2026 12:54:59 -0700 Subject: [PATCH 2/2] Update test --- .../http/pipeline/stages/AuthSchemeResolutionStageTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AuthSchemeResolutionStageTest.java b/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AuthSchemeResolutionStageTest.java index da86f97f053f..51e79f5ed01d 100644 --- a/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AuthSchemeResolutionStageTest.java +++ b/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AuthSchemeResolutionStageTest.java @@ -147,7 +147,7 @@ void execute_withIdentityProviderUpdater_callsUpdaterWithRequest() throws Except IdentityProviders updatedProviders = mock(IdentityProviders.class); IdentityProviderUpdater updater = mock(IdentityProviderUpdater.class); - doReturn(updatedProviders).when(updater).update(sdkRequest, baseProviders); + doReturn(updatedProviders).when(updater).update(sdkRequest, baseProviders, executionAttributes); // Setup so that auth scheme uses the updated providers @SuppressWarnings("unchecked") @@ -162,7 +162,7 @@ void execute_withIdentityProviderUpdater_callsUpdaterWithRequest() throws Except stage.execute(httpRequestBuilder, context); - verify(updater).update(sdkRequest, baseProviders); + verify(updater).update(sdkRequest, baseProviders, executionAttributes); } @Test