You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用RoleArn连接AWS S3 Client报错,请求排查问题

问题

尝试使用RoleArn替代静态SecretKey和AccessKey连接AWS S3 Client。已为该RoleArn配置信任关系(允许s3.amazonaws.com执行sts:AssumeRole),并附加了包含S3操作权限的策略,但运行时出现无法从任何凭证提供链加载AWS凭证的报错,请问是否存在配置遗漏?

信任关系配置

{
 "Version": "2012-10-17",
 "Statement": [
  {
   "Sid": "",
   "Effect": "Allow",
   "Principal": {
    "Service": "s3.amazonaws.com"
   },
   "Action": "sts:AssumeRole"
  }
 ]
}

S3权限策略

{
 ...,
 {
  "Action": [
   "s3:CreateBucket",
   "s3:DeleteBucket",
   "s3:DeleteObject",
   "s3:Get*",
   "s3:Put*"
  ],
  "Effect": "Allow",
  "Resource": "arn:aws:s3:::*partOfMyBucketName*"
 }
}

Java配置代码

@Configuration
public class AwsS3Configuration {

@Value("${aws.roleArn}")
private String roleARN;

@Bean
public AmazonS3 awsS3client() {
 try {
  AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard()
   .withRegion(US_EAST_1)
   .build();
  AssumeRoleRequest roleRequest = new AssumeRoleRequest()
   .withRoleArn(roleARN)
   .withRoleSessionName("sessionName");
  AssumeRoleResult roleResponse = stsClient.assumeRole(roleRequest);
  Credentials sessionCredentials = roleResponse.getCredentials();
  BasicSessionCredentials awsCredentials = new BasicSessionCredentials(
   sessionCredentials.getAccessKeyId(),
   sessionCredentials.getSecretAccessKeyId(),
   sessionCredentials.getSessionToken()
  );
  return AmazonS3ClientBuilder.standard()
   .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
   .withRegion(US_EAST_1)
   .build();
 } catch (AmazonServiceException e) {
  e.printStackTrace();
 } catch (SdkClientException e) {
  e.printStackTrace();
 }
 return null;
}

报错信息

com.amazonaws.SdkClientException: Unable to load AWS credentials from any provider in the chain: [EnvironmentVariableCredentialsProvider: Unable to load AWS credentials from envrionment 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: Unable to execute HTTP request: Connect to sts.us-east-1.amazonaws.com:443 [sts.us-east-1.amazonaws.com/209.54.177.185] failed: Connect timed out, com.amazonaws.auth.profile.ProfileCredentialsProvider@2de0f3e3: profile file cannot be null, com.amazonaws.auth.EC2ContainerCredentialsProviderWrapper@6f102740: Failed to connect to service endpoint: ]

解答

你的配置存在3个关键问题,直接导致凭证加载失败:

  • STS客户端缺少初始凭证
    你创建的AWSSecurityTokenService客户端未指定凭证提供者,默认走AWS凭证链加载,但你的环境中没有任何可用凭证(从报错可见环境变量、系统属性、配置文件、EC2元数据均无有效凭证),连STS服务都无法访问,自然无法调用assumeRole获取临时凭证。

  • 信任关系配置错误
    当前信任关系允许s3.amazonaws.com服务角色扮演该角色,但你的场景是Java应用主动调用STS AssumeRole,并非S3服务自身需要扮演角色。因此Principal应改为应用所在环境的身份(如EC2实例角色、IAM用户ARN、跨账号的账号ID等),而非s3.amazonaws.com。

  • 未处理临时凭证过期
    临时凭证默认有效期1小时,当前代码手动获取的凭证过期后,S3客户端会直接失效,没有自动刷新机制。

修复方案

方案1:使用IAM角色(推荐,适用于AWS环境内运行)

如果应用在AWS环境(EC2、ECS、EKS、Lambda等)运行,直接给运行环境绑定拥有S3操作权限的IAM角色,无需手动调用AssumeRole。S3客户端可简化为:

@Bean
public AmazonS3 awsS3client() {
    return AmazonS3ClientBuilder.standard()
            .withRegion(US_EAST_1)
            .build();
}

客户端会自动从环境获取IAM角色的临时凭证,并自动处理凭证刷新。

方案2:正确配置AssumeRole(适用于非AWS环境或跨账号场景)

若必须使用AssumeRole,需完成以下调整:

  1. 修正信任关系:将Principal改为允许你的源身份,例如允许某个IAM用户扮演该角色:
{
 "Version": "2012-10-17",
 "Statement": [
  {
   "Effect": "Allow",
   "Principal": {
    "AWS": "arn:aws:iam::你的账号ID:user/用户名"
   },
   "Action": "sts:AssumeRole"
  }
 ]
}
  1. 给STS客户端提供初始凭证:比如通过环境变量初始化STS客户端:
AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard()
        .withRegion(US_EAST_1)
        .withCredentials(new EnvironmentVariableCredentialsProvider())
        .build();
  1. 自动处理凭证过期:使用STSAssumeRoleSessionCredentialsProvider自动刷新临时凭证,替代手动调用AssumeRole:
@Bean
public AmazonS3 awsS3client() {
    STSAssumeRoleSessionCredentialsProvider credentialsProvider = new STSAssumeRoleSessionCredentialsProvider.Builder(roleARN, "sessionName")
            .withRegion(US_EAST_1)
            .build();
    return AmazonS3ClientBuilder.standard()
            .withCredentials(credentialsProvider)
            .withRegion(US_EAST_1)
            .build();
}

方案3:检查网络连接

报错提到连接STS服务超时,需确保应用所在环境能访问sts.us-east-1.amazonaws.com的443端口,无防火墙或代理拦截。

内容的提问来源于stack exchange,提问作者Karol Katanowski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 21:54:54