如何启用对 AWS STS AssumeRole 的访问
How enable access to AWS STS AssumeRole
调用 STS 的 assume role
方法时出错。它表示用户无权对资源 xxx
.
执行 sts:AsumeRole
我做了以下事情:
- 我创建了一个角色来访问 S3 存储桶。
- 我 运行 对策略模拟器进行了测试并且工作正常
- 我创建了一个新组,并在其中创建了一个新策略
在所有资源上启用所有 sts 操作。
- 我运行用policy simulator测试了一下,给sts assume role,指点
在第一步创建的角色的 ARN;而且效果很好
- 我创建了一个新用户,并将其放入第 3 步创建的组中
- 根据新用户的凭据,我尝试获取新的凭据
使用 sts asume 角色,但给我一个错误,说我的用户不是
授权执行 sts:AssumeRole
我做错了什么?
组中的策略
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "some-large-id",
"Effect": "Allow",
"Action": [
"sts:*"
],
"Resource": [
"*"
]
}
]
}
政策生效
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "another-large-id",
"Effect": "Allow",
"Action": [
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::my-bucket-name/*"
]
}
]
}
最后这样调用
let policy = {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "new-custom-id",
"Effect": "Allow",
"Action": ["s3:PutObject"],
"Resource": ["arn:aws:s3:::my-bucket-name/*"]
}
]
};
let params = {
DurationSeconds: 3600,
ExternalId: 'some-value',
Policy: JSON.stringify(policy),
RoleArn: "arn:aws:iam::NUMBER:role/ROLE-NAME", //Cheked, role is the same that step one
RoleSessionName: this.makeNewSessionId()
};
let sts = new AWS.STS({ apiVersion: '2012-08-10' });
sts.assumeRole(params, (err, data) => {
if(err) console.log(err);
else console.log(data);
});
缺少一个步骤:为在第一步中创建的角色设置信任关系。不管用户有什么权限,如果没有设置信任关系,STS都会拒绝请求。
Troubleshooting IAM Roles 解释它是如何工作的。
在你想承担的角色上,比如使用STSJavaV2API(不是Node),你需要设置信任关系。在信任关系中,指定要信任的用户。例如:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<AWS Account ID>:user/JohnDoe” //Specify the AWS ARN of your IAM user.
},
"Action": "sts:AssumeRole"
}
]
}
例如,现在您可以 运行 一个 Java 程序来调用 assumeRole 操作。
package com.example.sts;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sts.StsClient;
import software.amazon.awssdk.services.sts.model.AssumeRoleRequest;
import software.amazon.awssdk.services.sts.model.StsException;
import software.amazon.awssdk.services.sts.model.AssumeRoleResponse;
import software.amazon.awssdk.services.sts.model.Credentials;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Locale;
/**
* To make this code example work, create a Role that you want to assume.
* Then define a Trust Relationship in the AWS Console. YOu can use this as an example:
*
* {
* "Version": "2012-10-17",
* "Statement": [
* {
* "Effect": "Allow",
* "Principal": {
* "AWS": "<Specify the ARN of your IAM user you are using in this code example>"
* },
* "Action": "sts:AssumeRole"
* }
* ]
* }
*
* For more information, see "Editing the Trust Relationship for an Existing Role" in the AWS Directory Service guide.
*/
public class AssumeRole {
public static void main(String[] args) {
String roleArn = "arn:aws:iam::000540000000:role/s3role" ; // args[0];
String roleSessionName = "mysession101"; // args[1];
Region region = Region.US_EAST_1;
StsClient stsClient = StsClient.builder()
.region(region)
.build();
try {
AssumeRoleRequest roleRequest = AssumeRoleRequest.builder()
.roleArn(roleArn)
.roleSessionName(roleSessionName)
.build();
AssumeRoleResponse roleResponse = stsClient.assumeRole(roleRequest);
Credentials myCreds = roleResponse.credentials();
//Display the time when the temp creds expire
Instant exTime = myCreds.expiration();
// Convert the Instant to readable date
DateTimeFormatter formatter =
DateTimeFormatter.ofLocalizedDateTime( FormatStyle.SHORT )
.withLocale( Locale.US)
.withZone( ZoneId.systemDefault() );
formatter.format( exTime );
System.out.println("The temporary credentials expire on " + exTime );
} catch (StsException e) {
System.err.println(e.getMessage());
System.exit(1);
}
}
}
如果不设置信任关系,此代码将不起作用。
我遇到了同样的问题。这些步骤我固定如下:
- 创建新角色附加策略:AmazonS3FullAccess,(复制角色 ARN,在下面的代码中使用)
- Select 信任关系选项卡 - 编辑信任关系
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::IAM_USER_ID:user/haipv",//the roleARN need to be granted, use * for all
"Service": "s3.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
- 更新信任关系
示例代码:
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.BasicSessionCredentials;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.securitytoken.AWSSecurityTokenService;
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder;
import com.amazonaws.services.securitytoken.model.AssumeRoleRequest;
import com.amazonaws.services.securitytoken.model.AssumeRoleResult;
import com.amazonaws.services.securitytoken.model.Credentials;
public class Main {
public static void main(String[] args) {
Regions clientRegion = Regions.AP_SOUTHEAST_1;
String roleARN = "arn:aws:iam::IAM_USER_ID:role/haipvRole"; // the roleARN coppied above
String roleSessionName = "haipv-session";
String bucketName = "haipv.docketName";//file_example_MP4_640_3MG.mp4
String accesskey = "YOURKEY";
String secretkey = "YOUR SECRET KEY";
try {
BasicAWSCredentials credentials = new BasicAWSCredentials(accesskey, secretkey);
// Creating the STS client is part of your trusted code. It has
// the security credentials you use to obtain temporary security credentials.
AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withRegion(clientRegion)
.build();
// Obtain credentials for the IAM role. Note that you cannot assume the role of an AWS root account;
// Amazon S3 will deny access. You must use credentials for an IAM user or an IAM role.
AssumeRoleRequest roleRequest = new AssumeRoleRequest()
.withRoleArn(roleARN)
.withRoleSessionName(roleSessionName);
AssumeRoleResult roleResponse = stsClient.assumeRole(roleRequest);
Credentials sessionCredentials = roleResponse.getCredentials();
// Create a BasicSessionCredentials object that contains the credentials you just retrieved.
BasicSessionCredentials awsCredentials = new BasicSessionCredentials(
sessionCredentials.getAccessKeyId(),
sessionCredentials.getSecretAccessKey(),
sessionCredentials.getSessionToken());
// Provide temporary security credentials so that the Amazon S3 client
// can send authenticated requests to Amazon S3. You create the client
// using the sessionCredentials object.
AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
.withRegion(clientRegion)
.build();
// Verify that assuming the role worked and the permissions are set correctly
// by getting a set of object keys from the bucket.
ObjectListing objects = s3Client.listObjects(bucketName);
System.out.println("No. of Objects: " + objects.getObjectSummaries().size());
}
catch(AmazonServiceException e) {
// The call was transmitted successfully, but Amazon S3 couldn't process
// it, so it returned an error response.
e.printStackTrace();
}
catch(SdkClientException e) {
// Amazon S3 couldn't be contacted for a response, or the client
// couldn't parse the response from Amazon S3.
e.printStackTrace();
}
}
}
参考官方文档this link
对我有用。
在我的例子中,除了在 Trust relationship
选项卡下添加 "Action": "sts:AssumeRole"
(针对特定 ARN)之外,我还必须在 Permissions
选项卡中添加以下内容:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Resource": "*"
}
]
}
除了设置信任关系外,如果您环境中配置的区域是启用的区域之一,例如af-south-1 并且该区域未在您承担的角色的帐户中启用,您将收到未经授权的错误。即使您的所有权限都已正确配置,也是如此。
调用 STS 的 assume role
方法时出错。它表示用户无权对资源 xxx
.
sts:AsumeRole
我做了以下事情:
- 我创建了一个角色来访问 S3 存储桶。
- 我 运行 对策略模拟器进行了测试并且工作正常
- 我创建了一个新组,并在其中创建了一个新策略 在所有资源上启用所有 sts 操作。
- 我运行用policy simulator测试了一下,给sts assume role,指点 在第一步创建的角色的 ARN;而且效果很好
- 我创建了一个新用户,并将其放入第 3 步创建的组中
- 根据新用户的凭据,我尝试获取新的凭据 使用 sts asume 角色,但给我一个错误,说我的用户不是 授权执行 sts:AssumeRole
我做错了什么?
组中的策略
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "some-large-id",
"Effect": "Allow",
"Action": [
"sts:*"
],
"Resource": [
"*"
]
}
]
}
政策生效
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "another-large-id",
"Effect": "Allow",
"Action": [
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::my-bucket-name/*"
]
}
]
}
最后这样调用
let policy = {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "new-custom-id",
"Effect": "Allow",
"Action": ["s3:PutObject"],
"Resource": ["arn:aws:s3:::my-bucket-name/*"]
}
]
};
let params = {
DurationSeconds: 3600,
ExternalId: 'some-value',
Policy: JSON.stringify(policy),
RoleArn: "arn:aws:iam::NUMBER:role/ROLE-NAME", //Cheked, role is the same that step one
RoleSessionName: this.makeNewSessionId()
};
let sts = new AWS.STS({ apiVersion: '2012-08-10' });
sts.assumeRole(params, (err, data) => {
if(err) console.log(err);
else console.log(data);
});
缺少一个步骤:为在第一步中创建的角色设置信任关系。不管用户有什么权限,如果没有设置信任关系,STS都会拒绝请求。
Troubleshooting IAM Roles 解释它是如何工作的。
在你想承担的角色上,比如使用STSJavaV2API(不是Node),你需要设置信任关系。在信任关系中,指定要信任的用户。例如:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<AWS Account ID>:user/JohnDoe” //Specify the AWS ARN of your IAM user.
},
"Action": "sts:AssumeRole"
}
]
}
例如,现在您可以 运行 一个 Java 程序来调用 assumeRole 操作。
package com.example.sts;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sts.StsClient;
import software.amazon.awssdk.services.sts.model.AssumeRoleRequest;
import software.amazon.awssdk.services.sts.model.StsException;
import software.amazon.awssdk.services.sts.model.AssumeRoleResponse;
import software.amazon.awssdk.services.sts.model.Credentials;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Locale;
/**
* To make this code example work, create a Role that you want to assume.
* Then define a Trust Relationship in the AWS Console. YOu can use this as an example:
*
* {
* "Version": "2012-10-17",
* "Statement": [
* {
* "Effect": "Allow",
* "Principal": {
* "AWS": "<Specify the ARN of your IAM user you are using in this code example>"
* },
* "Action": "sts:AssumeRole"
* }
* ]
* }
*
* For more information, see "Editing the Trust Relationship for an Existing Role" in the AWS Directory Service guide.
*/
public class AssumeRole {
public static void main(String[] args) {
String roleArn = "arn:aws:iam::000540000000:role/s3role" ; // args[0];
String roleSessionName = "mysession101"; // args[1];
Region region = Region.US_EAST_1;
StsClient stsClient = StsClient.builder()
.region(region)
.build();
try {
AssumeRoleRequest roleRequest = AssumeRoleRequest.builder()
.roleArn(roleArn)
.roleSessionName(roleSessionName)
.build();
AssumeRoleResponse roleResponse = stsClient.assumeRole(roleRequest);
Credentials myCreds = roleResponse.credentials();
//Display the time when the temp creds expire
Instant exTime = myCreds.expiration();
// Convert the Instant to readable date
DateTimeFormatter formatter =
DateTimeFormatter.ofLocalizedDateTime( FormatStyle.SHORT )
.withLocale( Locale.US)
.withZone( ZoneId.systemDefault() );
formatter.format( exTime );
System.out.println("The temporary credentials expire on " + exTime );
} catch (StsException e) {
System.err.println(e.getMessage());
System.exit(1);
}
}
}
如果不设置信任关系,此代码将不起作用。
我遇到了同样的问题。这些步骤我固定如下:
- 创建新角色附加策略:AmazonS3FullAccess,(复制角色 ARN,在下面的代码中使用)
- Select 信任关系选项卡 - 编辑信任关系
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::IAM_USER_ID:user/haipv",//the roleARN need to be granted, use * for all "Service": "s3.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
- 更新信任关系
示例代码:
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.BasicSessionCredentials;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.securitytoken.AWSSecurityTokenService;
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder;
import com.amazonaws.services.securitytoken.model.AssumeRoleRequest;
import com.amazonaws.services.securitytoken.model.AssumeRoleResult;
import com.amazonaws.services.securitytoken.model.Credentials;
public class Main {
public static void main(String[] args) {
Regions clientRegion = Regions.AP_SOUTHEAST_1;
String roleARN = "arn:aws:iam::IAM_USER_ID:role/haipvRole"; // the roleARN coppied above
String roleSessionName = "haipv-session";
String bucketName = "haipv.docketName";//file_example_MP4_640_3MG.mp4
String accesskey = "YOURKEY";
String secretkey = "YOUR SECRET KEY";
try {
BasicAWSCredentials credentials = new BasicAWSCredentials(accesskey, secretkey);
// Creating the STS client is part of your trusted code. It has
// the security credentials you use to obtain temporary security credentials.
AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withRegion(clientRegion)
.build();
// Obtain credentials for the IAM role. Note that you cannot assume the role of an AWS root account;
// Amazon S3 will deny access. You must use credentials for an IAM user or an IAM role.
AssumeRoleRequest roleRequest = new AssumeRoleRequest()
.withRoleArn(roleARN)
.withRoleSessionName(roleSessionName);
AssumeRoleResult roleResponse = stsClient.assumeRole(roleRequest);
Credentials sessionCredentials = roleResponse.getCredentials();
// Create a BasicSessionCredentials object that contains the credentials you just retrieved.
BasicSessionCredentials awsCredentials = new BasicSessionCredentials(
sessionCredentials.getAccessKeyId(),
sessionCredentials.getSecretAccessKey(),
sessionCredentials.getSessionToken());
// Provide temporary security credentials so that the Amazon S3 client
// can send authenticated requests to Amazon S3. You create the client
// using the sessionCredentials object.
AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
.withRegion(clientRegion)
.build();
// Verify that assuming the role worked and the permissions are set correctly
// by getting a set of object keys from the bucket.
ObjectListing objects = s3Client.listObjects(bucketName);
System.out.println("No. of Objects: " + objects.getObjectSummaries().size());
}
catch(AmazonServiceException e) {
// The call was transmitted successfully, but Amazon S3 couldn't process
// it, so it returned an error response.
e.printStackTrace();
}
catch(SdkClientException e) {
// Amazon S3 couldn't be contacted for a response, or the client
// couldn't parse the response from Amazon S3.
e.printStackTrace();
}
}
}
参考官方文档this link
对我有用。
在我的例子中,除了在 Trust relationship
选项卡下添加 "Action": "sts:AssumeRole"
(针对特定 ARN)之外,我还必须在 Permissions
选项卡中添加以下内容:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Resource": "*"
}
]
}
除了设置信任关系外,如果您环境中配置的区域是启用的区域之一,例如af-south-1 并且该区域未在您承担的角色的帐户中启用,您将收到未经授权的错误。即使您的所有权限都已正确配置,也是如此。