Reputation: 330
I can't reach aws when my login is made using AWS SSO. I login from my computer using:
aws sso login --profile staging
The profile is configured like this:
[profile staging]
sso_start_url = https://som-nice-working-url
sso_region = us-east-1
sso_account_id = 1234
sso_role_name = the-role-name
region = eu-west-1
output = yaml
After doing the login I can access aws through aws cli.
Then I set the varible: AWS_PROFILE=staging
But on java I'm getting the following exception:
com.amazonaws.SdkClientException: Unable to load AWS credentials from any provider in the chain: [EnvironmentVariableCredentialsProvider: Unable to load AWS credentials from environment variables (AWS_ACCESS_KEY_ID (or AWS_ACCESS_KEY) and AWS_SECRET_KEY (or AWS_SECRET_ACCESS_KEY)), SystemPropertiesCredentialsProvider: Unable to load AWS credentials from Java system properties (aws.accessKeyId and aws.secretKey), WebIdentityTokenCredentialsProvider: You must specify a value for roleArn and roleSessionName, com.amazonaws.auth.profile.ProfileCredentialsProvider@369a95a5: No AWS profile named 'staging', com.amazonaws.auth.EC2ContainerCredentialsProviderWrapper@6d6f6ca9: Failed to connect to service endpoint: ]
I have tryed using the ProfileCredentialsProvider with "staging" but the result is the same.
What CredentialsProvider
should I use?
My code is using the DefaultProviderChain:
AWSGlueClient.builder()
.withRegion("eu-west-1")
.build()
Thank you.
Upvotes: 29
Views: 36953
Reputation: 1842
For a Java application you'll need the SSO Dependency.
As of writing the latest is version 2.16.76
// Gradle example
dependencies {
implementation(platform("software.amazon.awssdk:bom:2.16.76"))
implementation("software.amazon.awssdk:sso")
implementation("software.amazon.awssdk:ssooidc")
}
You'll also need to set a default
profile in either ~/.aws/configuration
or ~/.aws/credentials
More info below:
https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/credentials.html https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup.html#setup-credentials https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup-additional.html#setup-additional-credentials
But, you should also be able to just set the AWS_PROFILE
environment variable to your profile and it should just magically work without the SSO dependency.
In your example, specifically:
AWS_PROFILE=staging
Upvotes: 25
Reputation: 1152
This is an enhanced answers's @nluk provided. You just need the iam profile name to get the sso profile from the .aws
folder and config
file.
Add this in the pom:
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>sso</artifactId>
<version>2.19.16</version>
</dependency>
then: you can use sdk2 sso tooling:
import software.amazon.awssdk.auth.credentials.AwsSessionCredentials;
import software.amazon.awssdk.auth.credentials.ProfileProviderCredentialsContext;
import software.amazon.awssdk.profiles.ProfileFile;
import software.amazon.awssdk.services.sso.auth.SsoProfileCredentialsProviderFactory;
//....
String awsProfile = "my-profile-name"
ProfileFile profileFile = ProfileFile.defaultProfileFile();
profileFile
.getSection("profiles", awsProfile)
.ifPresent(
profile -> {
ProfileProviderCredentialsContext profileProvider =
ProfileProviderCredentialsContext.builder()
.profile(profile)
.profileFile(profileFile)
.build();
// cast to get the token
AwsSessionCredentials awsCredentials =
(AwsSessionCredentials)
new SsoProfileCredentialsProviderFactory()
.create(profileProvider)
.resolveCredentials();
// then get the temporary credentials
// awsCredentials.accessKeyId();
// awsCredentials.secretAccessKey();
// awsCredentials.sessionToken();
});
Upvotes: 1
Reputation: 894
When using AWS SDK for Java, you could try giving some environment variables to your Java applicatation using values from the cached temporary credentials.
Login using:
aws sso login
Read the cached file:
cat ~/.aws/cli/cache/<generated>.json
Set your environment variables using fields from the cached file:
AWS_ACCESS_KEY_ID=<AccessKeyId>
AWS_SECRET_ACCESS_KEY=<SecretAccessKey>
AWS_SESSION_TOKEN=<SessionToken>
Run your Java application using these environment variables.
Under the hood, the EnvironmentVariableCredentialsProvider class reads these environment variables.
You will need to reset these environment variables every time the session token expires.
Upvotes: 0
Reputation: 754
In my case, just adding the aws-sso dependency:
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>sso</artifactId>
</dependency>
allows the default credentials providers chain to pick up sso under ProfileCredentialsProvider
:
To work out of the box, it requires from you to have the [default]
profile specified. Otherwise, simply using .credentialsProvider(ProfileCredentialsProvider.create("xyz"))
also works with [profile xyz]
.
If all fails, add the credentials provider manually:
.aws/config
aws sso login --profile <your_profile>
.aws/sso/cache
with contents as described here{
"startUrl": "https://my-sso-portal.awsapps.com/start",
"region": "us-east-1",
"accessToken": "eyJlbmMiOiJBM….",
"expiresAt": "2020-06-17T10:02:08UTC"
}
software.amazon.awssdk:sso
SsoCredentialsProvider
with the data from json file:CredentialsProvider ssoCredentialsProvider = ((SsoCredentialsProvider.Builder) SsoCredentialsProvider.builder())
.ssoClient(SsoClient.builder().region(<REGION_FROM_JSON>).build())
.refreshRequest( () ->
GetRoleCredentialsRequest.builder()
.roleName("<ROLE_FROM_PROFILE>")
.accountId("<ACCOUNT_ID_FROM_PROFILE>")
.accessToken("<ACCESS_TOKEN_FROM_JSON>")
.build()
).build();
Upvotes: 9
Reputation: 13228
Support for SSO Credentials Provider was added to AWS SDK for Java V2 in version 2.15.33
(November 2020). Older versions of the SDK don't work with SSO. (See the Feature Request & the PR)
If you are using maven, make sure the versions of all SDK modules are compatible by specifying the version in the dependencyManagement
section as described in the documentation. e.g.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bom</artifactId>
<version>2.17.8</version> <!--Must be 2.15.33 or higher-->
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>dynamodb</artifactId>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>sso</artifactId>
</dependency>
</dependencies>
Upvotes: 10
Reputation: 1526
Waiting for SDK 2 to integrate SSO, aws-sso-cred-restore
is a workaround:
Intall it (with Python 3):
pip3 install aws-sso-cred-restore
Then you can run this (it get a Token available for around 1h, so you should run it every hour to refresh):
aws-sso-cred-restore --profile $YOUR_PROFILE
And you can use again your $YOUR_PROFILE in your Java app.
Upvotes: 1
Reputation: 2787
I might be wrong, however IMO there is no way to use AWS SSO within AWS SDK yet based on https://docs.aws.amazon.com/sdk-for-java/v2/developer-guide/credentials.html.
AFAIK AWS SSO is at the moment integrated only into AWS CLI - https://docs.aws.amazon.com/singlesignon/latest/userguide/integrating-aws-cli.html
Upvotes: 1