AWS Java SDK在使用AWS SSO时无法找到配置文件。

huangapple go评论76阅读模式
英文:

AWS Java SDK not finding profile when using AWS SSO

问题

我使用AWS SSO登录时无法访问AWS。我从计算机上使用以下方式登录:

aws sso login --profile staging

配置文件如下:

[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

完成登录后,我可以通过aws cli访问AWS。

然后我设置了变量:AWS_PROFILE=staging
但在Java中,我遇到了以下异常:

com.amazonaws.SdkClientException: 无法从链中的任何提供程序加载AWS凭证:[EnvironmentVariableCredentialsProvider:无法从环境变量(AWS_ACCESS_KEY_ID(或AWS_ACCESS_KEY)和AWS_SECRET_KEY(或AWS_SECRET_ACCESS_KEY))加载AWS凭证,SystemPropertiesCredentialsProvider:无法从Java系统属性(aws.accessKeyId和aws.secretKey)加载AWS凭证,WebIdentityTokenCredentialsProvider:您必须为roleArn和roleSessionName指定值,com.amazonaws.auth.profile.ProfileCredentialsProvider@369a95a5:没有名为'staging'的AWS配置文件,com.amazonaws.auth.EC2ContainerCredentialsProviderWrapper@6d6f6ca9:无法连接到服务端点:]

我尝试过使用ProfileCredentialsProvider并将其设置为“staging”,但结果相同。

我应该使用哪个CredentialsProvider

我的代码正在使用DefaultProviderChain:

AWSGlueClient.builder()
            .withRegion("eu-west-1")
            .build()

谢谢。

英文:

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.

答案1

得分: 15

对于一个Java应用程序,您将需要SSO依赖库

截至撰写本文时,最新版本为2.16.76

// Gradle示例
dependencies {
    implementation(platform("software.amazon.awssdk:bom:2.16.70"))
    implementation("software.amazon.awssdk:sso:2.16.76")
}

您还需要在~/.aws/configuration~/.aws/credentials中设置一个default配置文件。

更多信息如下:

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

但是,您还可以将AWS_PROFILE环境变量设置为您的配置文件,这样它应该可以在没有SSO依赖的情况下自动工作。

在您的示例中,特别是:

AWS_PROFILE=staging
英文:

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.70"))
    implementation("software.amazon.awssdk:sso:2.16.76")
}

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

答案2

得分: 6

在我的情况下,只需添加aws-sso依赖项:

<dependency>
   <groupId>software.amazon.awssdk</groupId>
   <artifactId>sso</artifactId>
</dependency>

允许默认凭据提供程序链在ProfileCredentialsProvider下获取sso:

AWS Java SDK在使用AWS SSO时无法找到配置文件。

要让其开箱即用工作,您需要在配置文件中指定[default]配置文件。否则,也可以使用.credentialsProvider(ProfileCredentialsProvider.create("xyz"))[profile xyz]一起使用。

如果一切都失败了,请手动添加凭据提供程序:

  1. 设置您的配置文件.aws/config
  2. 使用cli登录 aws sso login --profile <your_profile>
  3. .aws/sso/cache中生成一个包含以下内容的json文件,详情描述在这里
{
 "startUrl": "https://my-sso-portal.awsapps.com/start",
 "region": "us-east-1",
 "accessToken": "eyJlbmMiOiJBM….",
 "expiresAt": "2020-06-17T10:02:08UTC"
}
  1. 在项目中添加一个依赖项 software.amazon.awssdk:sso
  2. 使用json文件中的数据创建SsoCredentialsProvider
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();
英文:

In my case, just adding the aws-sso dependency:

    &lt;dependency&gt;
       &lt;groupId&gt;software.amazon.awssdk&lt;/groupId&gt;
       &lt;artifactId&gt;sso&lt;/artifactId&gt;
    &lt;/dependency&gt;

allows the default credentials providers chain to pick up sso under ProfileCredentialsProvider:
AWS Java SDK在使用AWS SSO时无法找到配置文件。

To work out of the box, it requires from you to have the [default] profile specified. Otherwise, simply using .credentialsProvider(ProfileCredentialsProvider.create(&quot;xyz&quot;)) also works with [profile xyz].

If all fails, add the credentials provider manually:

  1. Setup your profile file .aws/config
  2. Login with cli aws sso login --profile &lt;your_profile&gt;
  3. A json file is generated in .aws/sso/cache with contents as described here
{
 &quot;startUrl&quot;: &quot;https://my-sso-portal.awsapps.com/start&quot;,
 &quot;region&quot;: &quot;us-east-1&quot;,
 &quot;accessToken&quot;: &quot;eyJlbmMiOiJBM….&quot;,
 &quot;expiresAt&quot;: &quot;2020-06-17T10:02:08UTC&quot;
}
  1. Include in your project a dependency to software.amazon.awssdk:sso
  2. Create SsoCredentialsProvider with the data from json file:
CredentialsProvider ssoCredentialsProvider = ((SsoCredentialsProvider.Builder) SsoCredentialsProvider.builder())
.ssoClient(SsoClient.builder().region(&lt;REGION_FROM_JSON&gt;).build())
.refreshRequest( () -&gt;
    GetRoleCredentialsRequest.builder()
      .roleName(&quot;&lt;ROLE_FROM_PROFILE&gt;&quot;)
      .accountId(&quot;&lt;ACCOUNT_ID_FROM_PROFILE&gt;&quot;)
      .accessToken(&quot;&lt;ACCESS_TOKEN_FROM_JSON&gt;&quot;)
      .build()
).build();

答案3

得分: 4

在AWS SDK for Java V2的版本2.15.332020年11月)中添加了对SSO凭证提供程序的支持。旧版本的SDK不支持SSO。(参见功能请求PR

如果您正在使用Maven,请确保所有SDK模块的版本兼容,方法是在dependencyManagement部分中通过在文档中描述的方式指定版本。例如:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>bom</artifactId>
            <version>2.17.8</version>  <!--必须为2.15.33或更高版本-->
            <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>
英文:

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.

&lt;dependencyManagement&gt;
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;software.amazon.awssdk&lt;/groupId&gt;
            &lt;artifactId&gt;bom&lt;/artifactId&gt;
            &lt;version&gt;2.17.8&lt;/version&gt;  &lt;!--Must be 2.15.33 or higher--&gt;
            &lt;type&gt;pom&lt;/type&gt;
            &lt;scope&gt;import&lt;/scope&gt;
       &lt;/dependency&gt;
    &lt;/dependencies&gt;
&lt;/dependencyManagement&gt;

&lt;dependencies&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;software.amazon.awssdk&lt;/groupId&gt;
        &lt;artifactId&gt;dynamodb&lt;/artifactId&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
       &lt;groupId&gt;software.amazon.awssdk&lt;/groupId&gt;
       &lt;artifactId&gt;sso&lt;/artifactId&gt;
    &lt;/dependency&gt;
&lt;/dependencies&gt;

答案4

得分: 1

根据 https://docs.aws.amazon.com/sdk-for-java/v2/developer-guide/credentials.html,我可能是错误的,但在我个人看来,目前还没有办法在 AWS SDK 中使用 AWS SSO。

据我所知,目前 AWS SSO 只集成到了 AWS CLI 中,具体信息可见于 https://docs.aws.amazon.com/singlesignon/latest/userguide/integrating-aws-cli.html

英文:

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

答案5

得分: 1

等待SDK 2集成SSO,aws-sso-cred-restore是一个解决方法:

安装它(使用Python 3):

pip3 install aws-sso-cred-restore

然后你可以运行以下命令(它会获取一个大约1小时有效的令牌,所以你应该每小时运行一次以刷新):

aws-sso-cred-restore --profile $YOUR_PROFILE

然后你可以在你的Java应用程序中再次使用你的$YOUR_PROFILE

英文:

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.

答案6

得分: 1

使用AWS SDK for Java时,您可以尝试将一些环境变量传递给您的Java应用程序,使用来自缓存临时凭据的值。

使用以下命令登录:

aws sso login

读取缓存文件:

cat ~/.aws/cli/cache/<generated>.json

使用缓存文件中的字段设置您的环境变量:

AWS_ACCESS_KEY_ID=<AccessKeyId>
AWS_SECRET_ACCESS_KEY=<SecretAccessKey>
AWS_SESSION_TOKEN=<SessionToken>

使用这些环境变量运行您的Java应用程序。

在幕后,EnvironmentVariableCredentialsProvider类会读取这些环境变量。

每次会话令牌过期时,您需要重置这些环境变量。

英文:

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/&lt;generated&gt;.json

Set your environment variables using fields from the cached file:

AWS_ACCESS_KEY_ID=&lt;AccessKeyId&gt;
AWS_SECRET_ACCESS_KEY=&lt;SecretAccessKey&gt;
AWS_SESSION_TOKEN=&lt;SessionToken&gt;

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.

答案7

得分: 1

这是增强版的答案,由 @nluk 提供。你只需要 IAM 配置文件的名称,就可以从 .aws 文件夹和 config 文件中获取 SSO 配置文件。

将以下内容添加到 pom 文件中:

        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>sso</artifactId>
            <version>2.19.16</version>
        </dependency>

然后,你可以使用 SDK2 SSO 工具:

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();
//            转换以获取令牌
              AwsSessionCredentials awsCredentials =
                  (AwsSessionCredentials)
                      new SsoProfileCredentialsProviderFactory()
                          .create(profileProvider)
                          .resolveCredentials();
// 然后获取临时凭证
//            awsCredentials.accessKeyId();
//            awsCredentials.secretAccessKey();
//            awsCredentials.sessionToken();
            });

注意:请确保将 IAM 配置文件名称(my-profile-name)替换为实际的配置文件名称。

英文:

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:

        &lt;dependency&gt;
            &lt;groupId&gt;software.amazon.awssdk&lt;/groupId&gt;
            &lt;artifactId&gt;sso&lt;/artifactId&gt;
            &lt;version&gt;2.19.16&lt;/version&gt;
        &lt;/dependency&gt;

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 = &quot;my-profile-name&quot;
 ProfileFile profileFile = ProfileFile.defaultProfileFile();
    profileFile
        .getSection(&quot;profiles&quot;, awsProfile)
        .ifPresent(
            profile -&gt; {
              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();
            });

huangapple
  • 本文由 发表于 2020年9月25日 18:54:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/64062720.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定