简体   繁体   中英

Download and upload file using IAM role instead of secret and access key

I am using AmazonS3 client to download the file:

@Value("${cloud.aws.assumeRoleARN}")
private String assumeRoleARN;

@Bean
public AmazonS3Client generateS3Client() {
    AWSCredentialsProvider awsCredentialsProvider = roleCredentialsProvider();
    AmazonS3Client client = new AmazonS3Client(awsCredentialsProvider);
    return client;
}


@Bean
@Primary
public AWSCredentialsProvider roleCredentialsProvider() {
    String roleSessionName = "PP-Session-" + Thread.currentThread().getId();

    AssumeRoleRequest assumeRoleRequest = new AssumeRoleRequest();
    assumeRoleRequest.setRoleArn(assumeRoleARN);
    assumeRoleRequest.setExternalId("123");
    assumeRoleRequest.setRoleSessionName(roleSessionName);

    AWSSecurityTokenServiceClient stsClient = new AWSSecurityTokenServiceClient();
    stsClient.setRegion(Region.getRegion(Regions.EU_CENTRAL_1));

    STSAssumeRoleSessionCredentialsProvider.Builder builder = new  STSAssumeRoleSessionCredentialsProvider.Builder(assumeRoleARN,roleSessionName);

    STSAssumeRoleSessionCredentialsProvider stsAssumeRoleSessionCredentialsProvider = builder.withStsClient(stsClient).build();
    return stsAssumeRoleSessionCredentialsProvider;


}

My property config is as follows:

app.awsServices.bucketName=${S3_BUCKET_NAME}
cloud.aws.assumeRoleARN = arn:aws:iam::365991658844:role/external_id_role
cloud.aws.stack.auto=false
cloud.aws.region.static=eu-central-1

The role has trust entity defined as:

    {
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::365991658844:user/test"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "123"
        }
      }
    }
  ]
}

But I am repeatedly getting:

Roles may not be assumed by root accounts. (Service: AWSSecurityTokenService; Status Code: 403; Error Code: AccessDenied; Request ID: 96716339-ef10-4680-84d9-65117780c8d8)

You have several issues here.

The first is that you are running this program using the account's root credentials. Since you're using a no-arguments constructor for AWSSecurityTokenServiceClient , that means that you're either providing those credentials in environment variables or in $HOME/.aws/credentials (or $HOME/.aws/config ).

This is generally a bad practice, so your first step should be to create a new user for yourself. You will need to create access keys for this user, and change whatever configuration you're currently using to use those keys. And you should delete the access keys for your root user (along with using a very long random password and multi-factor authentication).

You could also use your "test" user to assume the role (assuming it as sts:AssumeRole permission). However, specifying a single user in a trust policy limits your flexibility: you must be using that user's credentials to assume the role. Which means that if you're running on EC2, or Lambda, you'll need to provide that user's credentials in configuration, which goes against Amazon's best practices .

A better approach to trust the entire AWS account and then use an explicit access policy for those users/groups/roles that can assume the role. That trust policy lookes like this (note that the "root" in this trust policy does not mean that it can be assumed by the account's root user):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:root"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

You can, if you want, add on a condition for external ID. Before you do this, however, you should ask whether it is appropriate to your situation . If you're not assuming this role from an unrelated account, there's no reason to use an external ID.

Next, each user/group/role that can assume this role must have a policy like this:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "sts:AssumeRole",
      "Resource": [
        "arn:aws:iam::123456789012:role/ExampleRole"
      ]
    }
  ]
}

Note that for all these examples, the account number 123456789012 should be replaced by the actual account(s) that you're using.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM