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

22

当我使用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: 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: ]

我已经尝试使用“staging”与ProfileCredentialsProvider,但结果相同。

我应该使用哪个CredentialsProvider

我的代码正在使用DefaultProviderChain:

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

谢谢你。

7个回答

18

如果要创建一个Java应用程序,您需要使用SSO依赖项

截至撰写本文,最新版本是2.16.76

// Gradle example
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

2
还要包括implementation("software.amazon.awssdk:ssooidc")以避免异常:"要在<profile>配置文件中使用SSO OIDC相关属性,必须将'ssooidc'服务模块添加到类路径中。" - hertzsprung

7

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

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

允许默认凭证提供程序链选择在ProfileCredentialsProvider下使用单点登录(SSO):

Profile credentials provider with sso profile

为了开箱即用,需要您指定[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();

4
在2020年11月的AWS SDK for Java V2版本2.15.33中新增了对SSO凭证提供程序的支持。旧版本的SDK不支持SSO。(请参见功能请求PR)
如果您使用maven,请确保通过在dependencyManagement部分指定版本来使所有SDK模块的版本兼容,如文档所述。例如:
<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>

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();
//            cast to get the token
              AwsSessionCredentials awsCredentials =
                  (AwsSessionCredentials)
                      new SsoProfileCredentialsProviderFactory()
                          .create(profileProvider)
                          .resolveCredentials();
// then get the temporary credentials
//            awsCredentials.accessKeyId();
//            awsCredentials.secretAccessKey();
//            awsCredentials.sessionToken();
            });

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类会读取这些环境变量。

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


1

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。


当配置文件为"default"时,它无法找到它,因为部分名称是[default] - Yijun Blue Yuan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接