This may be a bug, or a misunderstanding of how to use the 2.0 sdk to assume a role with SAML. In short, I would like to use Secure Token Service to authenticate with my Identity Provider and then once authenticated, assume a role in AWS to use when calling different services.
Expected Behavior
Currently, I am using the StsAssumeRoleWithSamlCredentialProvider. Once I configure the credential provider and give it a mechanism to get a valid saml assertion from my Identity Provider, I should be able to give that credential provider to any other service client so that it will use those credentials when making API calls. Those other services should NOT attempt to get credentials from any other sources ( this includes the DefaultCredentialProvider which looks in a myriad of places).
Current Behavior
When I pass the StsAssumeRoleWithSamlCredentialProvider to another service client ( such as CloudWatchLogsClient ), and initiate a request, the request fails with multiple "Unable to load credentials from ***" errors. Here is one of the stack traces:
[http-nio-8080-exec-1] DEBUG software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain - Unable to load credentials from SystemPropertyCredentialsProvider(): Unable to load credentials from system settings. Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) or system property (aws.accessKeyId). software.amazon.awssdk.core.exception.SdkClientException: Unable to load credentials from system settings. Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) or system property (aws.accessKeyId). at software.amazon.awssdk.core.exception.SdkClientException$BuilderImpl.build(SdkClientException.java:97) at software.amazon.awssdk.auth.credentials.internal.SystemSettingsCredentialsProvider.resolveCredentials(SystemSettingsCredentialsProvider.java:58) at software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain.resolveCredentials(AwsCredentialsProviderChain.java:91) at software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider.resolveCredentials(DefaultCredentialsProvider.java:92) at software.amazon.awssdk.awscore.client.handler.AwsClientHandlerUtils.createExecutionContext(AwsClientHandlerUtils.java:70) at software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler.createExecutionContext(AwsSyncClientHandler.java:68) at software.amazon.awssdk.core.client.handler.BaseSyncClientHandler.execute(BaseSyncClientHandler.java:68) at software.amazon.awssdk.core.client.handler.SdkSyncClientHandler.execute(SdkSyncClientHandler.java:44) at software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler.execute(AwsSyncClientHandler.java:55) at software.amazon.awssdk.services.sts.DefaultStsClient.assumeRoleWithSAML(DefaultStsClient.java:370) at software.amazon.awssdk.services.sts.auth.StsAssumeRoleWithSamlCredentialsProvider.getUpdatedCredentials(StsAssumeRoleWithSamlCredentialsProvider.java:69) at software.amazon.awssdk.services.sts.auth.StsCredentialsProvider.updateSessionCredentials(StsCredentialsProvider.java:68) at software.amazon.awssdk.utils.cache.CachedSupplier.refreshCache(CachedSupplier.java:132) at software.amazon.awssdk.utils.cache.CachedSupplier.get(CachedSupplier.java:89) at software.amazon.awssdk.services.sts.auth.StsCredentialsProvider.resolveCredentials(StsCredentialsProvider.java:78) at software.amazon.awssdk.services.sts.auth.StsAssumeRoleWithSamlCredentialsProvider.resolveCredentials(StsAssumeRoleWithSamlCredentialsProvider.java:42) at software.amazon.awssdk.awscore.client.handler.AwsClientHandlerUtils.createExecutionContext(AwsClientHandlerUtils.java:70) at software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler.createExecutionContext(AwsSyncClientHandler.java:68) at software.amazon.awssdk.core.client.handler.BaseSyncClientHandler.execute(BaseSyncClientHandler.java:68) at software.amazon.awssdk.core.client.handler.SdkSyncClientHandler.execute(SdkSyncClientHandler.java:44) at software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler.execute(AwsSyncClientHandler.java:55) at software.amazon.awssdk.services.cloudwatchlogs.DefaultCloudWatchLogsClient.getLogEvents(DefaultCloudWatchLogsClient.java:1836) at logs.GetAWSLogs.getLogs(GetAWSLogs.java:167)
What I think may be the cause of this issue is that the StsAssumeRoleWithSamlCredentialsProvider uses the StsClient to make the request. The default StsClient uses the DefaultCredentialsProvider to authenticate with AWS in order to make the request. You can override the credentials provider in the StsClient with the overrideConfiguration method, but since the StsAssumeRoleWithSamlCredentialsProvider requires the StsClient, it seems that its a "chicken and egg" scenario. You can't configure the Sts..CredentialsProvider without an StsClient, but the StsClient needs a credentials provider itself...
Guidance on how to correctly assume a role, or if this is truly a bug, then a quick fix would be very much appreciated.
Steps to Reproduce (for bugs)
`
ProxyConfiguration proxyConfig = null;
try {
proxyConfig = ProxyConfiguration
.builder()
.endpoint(new URI("http_proxy"))
.build();
} catch (URISyntaxException e) {
e.printStackTrace();
}
AWSSAMLAuthenticationConfiguration config = AWSSAMLAuthenticationConfiguration
.builder()
.userName(ad_user)
.userPass(ad_pass)
.roleName(aws_role)
.region(Region.US_EAST_1)
.proxyConfig(proxyConfig)
.build();
SdkHttpClient httpClient = ApacheHttpClient
.builder()
.proxyConfiguration(proxyConfig)
.build();
AssumeRoleWithSamlRequest request = AssumeRoleWithSamlRequest
.builder()
.durationSeconds(900)
.roleArn(ROLE_ARN)
.principalArn("PRINCIPAL_ARN")
.build();
SamlIdentityProviderServiceFactory factory = new SamlIdentityProviderServiceFactory();
SamlIdentityProviderService service = factory.getService(config);
Supplier<AssumeRoleWithSamlRequest> supplier = () ->
request.toBuilder()
.samlAssertion(service.getValidAssertion())
.build();
cp = StsAssumeRoleWithSamlCredentialsProvider
.builder()
.stsClient(StsClient.builder().region(Region.US_EAST_1).httpClient(httpClient).build())
.asyncCredentialUpdateEnabled(true)
.refreshRequest(supplier)
.build();
cw = CloudWatchLogsClient.builder()
.httpClient(httpClient)
.region(Region.US_EAST_1)
.credentialsProvider(cp)
.build();
GetLogEventsResponse logEventsResponse = cw.getLogEvents(GetLogEventsRequest.builder()
.logGroupName(logGroup)
.logStreamName(logStream)
.startFromHead(true)
.build());
`
Context
Without the ability to correctly assume a role via saml, we cannot migrate to the 2.0 version of the SDK.
Your Environment
- AWS Java SDK version used: 2.3.1
This may be a bug, or a misunderstanding of how to use the 2.0 sdk to assume a role with SAML. In short, I would like to use Secure Token Service to authenticate with my Identity Provider and then once authenticated, assume a role in AWS to use when calling different services.
Expected Behavior
Currently, I am using the StsAssumeRoleWithSamlCredentialProvider. Once I configure the credential provider and give it a mechanism to get a valid saml assertion from my Identity Provider, I should be able to give that credential provider to any other service client so that it will use those credentials when making API calls. Those other services should NOT attempt to get credentials from any other sources ( this includes the DefaultCredentialProvider which looks in a myriad of places).
Current Behavior
When I pass the StsAssumeRoleWithSamlCredentialProvider to another service client ( such as CloudWatchLogsClient ), and initiate a request, the request fails with multiple "Unable to load credentials from ***" errors. Here is one of the stack traces:
[http-nio-8080-exec-1] DEBUG software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain - Unable to load credentials from SystemPropertyCredentialsProvider(): Unable to load credentials from system settings. Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) or system property (aws.accessKeyId). software.amazon.awssdk.core.exception.SdkClientException: Unable to load credentials from system settings. Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) or system property (aws.accessKeyId). at software.amazon.awssdk.core.exception.SdkClientException$BuilderImpl.build(SdkClientException.java:97) at software.amazon.awssdk.auth.credentials.internal.SystemSettingsCredentialsProvider.resolveCredentials(SystemSettingsCredentialsProvider.java:58) at software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain.resolveCredentials(AwsCredentialsProviderChain.java:91) at software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider.resolveCredentials(DefaultCredentialsProvider.java:92) at software.amazon.awssdk.awscore.client.handler.AwsClientHandlerUtils.createExecutionContext(AwsClientHandlerUtils.java:70) at software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler.createExecutionContext(AwsSyncClientHandler.java:68) at software.amazon.awssdk.core.client.handler.BaseSyncClientHandler.execute(BaseSyncClientHandler.java:68) at software.amazon.awssdk.core.client.handler.SdkSyncClientHandler.execute(SdkSyncClientHandler.java:44) at software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler.execute(AwsSyncClientHandler.java:55) at software.amazon.awssdk.services.sts.DefaultStsClient.assumeRoleWithSAML(DefaultStsClient.java:370) at software.amazon.awssdk.services.sts.auth.StsAssumeRoleWithSamlCredentialsProvider.getUpdatedCredentials(StsAssumeRoleWithSamlCredentialsProvider.java:69) at software.amazon.awssdk.services.sts.auth.StsCredentialsProvider.updateSessionCredentials(StsCredentialsProvider.java:68) at software.amazon.awssdk.utils.cache.CachedSupplier.refreshCache(CachedSupplier.java:132) at software.amazon.awssdk.utils.cache.CachedSupplier.get(CachedSupplier.java:89) at software.amazon.awssdk.services.sts.auth.StsCredentialsProvider.resolveCredentials(StsCredentialsProvider.java:78) at software.amazon.awssdk.services.sts.auth.StsAssumeRoleWithSamlCredentialsProvider.resolveCredentials(StsAssumeRoleWithSamlCredentialsProvider.java:42) at software.amazon.awssdk.awscore.client.handler.AwsClientHandlerUtils.createExecutionContext(AwsClientHandlerUtils.java:70) at software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler.createExecutionContext(AwsSyncClientHandler.java:68) at software.amazon.awssdk.core.client.handler.BaseSyncClientHandler.execute(BaseSyncClientHandler.java:68) at software.amazon.awssdk.core.client.handler.SdkSyncClientHandler.execute(SdkSyncClientHandler.java:44) at software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler.execute(AwsSyncClientHandler.java:55) at software.amazon.awssdk.services.cloudwatchlogs.DefaultCloudWatchLogsClient.getLogEvents(DefaultCloudWatchLogsClient.java:1836) at logs.GetAWSLogs.getLogs(GetAWSLogs.java:167)What I think may be the cause of this issue is that the StsAssumeRoleWithSamlCredentialsProvider uses the StsClient to make the request. The default StsClient uses the DefaultCredentialsProvider to authenticate with AWS in order to make the request. You can override the credentials provider in the StsClient with the
overrideConfigurationmethod, but since the StsAssumeRoleWithSamlCredentialsProvider requires the StsClient, it seems that its a "chicken and egg" scenario. You can't configure the Sts..CredentialsProvider without an StsClient, but the StsClient needs a credentials provider itself...Guidance on how to correctly assume a role, or if this is truly a bug, then a quick fix would be very much appreciated.
Steps to Reproduce (for bugs)
`
ProxyConfiguration proxyConfig = null;
try {
proxyConfig = ProxyConfiguration
.builder()
.endpoint(new URI("http_proxy"))
.build();
} catch (URISyntaxException e) {
e.printStackTrace();
}
`
Context
Without the ability to correctly assume a role via saml, we cannot migrate to the 2.0 version of the SDK.
Your Environment