Загрузите и загрузите файл, используя роль IAM вместо секретного ключа и ключа доступа - PullRequest
0 голосов
/ 27 апреля 2020

Я использую клиент AmazonS3 для загрузки файла:

@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;


}

Моя конфигурация свойства выглядит следующим образом:

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

Роль имеет объект доверия, определенный как:

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

Но я постоянно получаю:

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

1 Ответ

0 голосов
/ 27 апреля 2020

У вас есть несколько проблем здесь.

Во-первых, вы запускаете эту программу, используя учетные данные root учетной записи. Поскольку вы используете конструктор без аргументов для AWSSecurityTokenServiceClient, это означает, что вы предоставляете эти учетные данные в переменных окружения или в $HOME/.aws/credentials (или $HOME/.aws/config).

Обычно это плохая практика, поэтому ваш первый шаг должен состоять в том, чтобы создать нового пользователя для себя. Вам нужно будет создать ключи доступа для этого пользователя и изменить любую конфигурацию, которую вы сейчас используете для использования этих ключей. И вы должны удалить ключи доступа для вашего root пользователя (наряду с использованием очень длинного случайного пароля и многофакторной аутентификации).

Вы также можете использовать своего «тестового» пользователя, чтобы взять на себя роль (предполагая, что это как sts:AssumeRole разрешение). Однако указание одного пользователя в политике доверия ограничивает вашу гибкость: вы должны использовать учетные данные этого пользователя для принятия роли. Это означает, что если вы работаете в EC2 или Lambda, вам необходимо предоставить учетные данные этого пользователя в конфигурации, что противоречит рекомендациям Amazon .

Более эффективный подход к доверию всей учетной записи AWS, а затем используйте явную политику доступа для тех пользователей / групп / ролей, которые могут взять на себя эту роль. Эта политика доверия выглядит следующим образом (обратите внимание, что «root» в этой политике доверия означает , а не означает, что пользователь учетной записи может * root):

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

Вы можете, если хотите, добавить условие для внешнего идентификатора. Однако, прежде чем сделать это, вы должны спросить, соответствует ли это вашей ситуации . Если вы не принимаете эту роль от несвязанной учетной записи, нет никаких причин использовать внешний идентификатор.

Далее, каждый пользователь / группа / роль, которая может предположить, что эта роль должна иметь такую ​​политику, должна иметь такую ​​политику:

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

Обратите внимание, что для всех этих примеров номер учетной записи 123456789012 должен быть заменен фактической учетной записью, которую вы используете.

...