如何从可用的BasicAWSCredentials中推断出AWS账户ID?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何从可用的BasicAWSCredentials中推断出AWS账户ID?相关的知识,希望对你有一定的参考价值。
似乎无法在文档中的任何地方找到它;如果我使用BasicAWSCredentials进行身份验证,例如AccessKeyId和SecretKey,是否可以获取AWS账户ID?
Update
AWS刚刚通过引入专用的STS API动作GetCallerIdentity来解决这个长期存在的差距,该动作返回有关其凭证用于调用API的IAM身份的详细信息,包括AWS账户ID - 有一些sample responses,例如:
<GetCallerIdentityResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/">
<GetCallerIdentityResult>
<Arn>arn:aws:iam::123456789012:user/Alice</Arn>
<UserId>AKIAI44QH8DHBEXAMPLE</UserId>
<Account>123456789012</Account>
</GetCallerIdentityResult>
<ResponseMetadata>
<RequestId>01234567-89ab-cdef-0123-456789abcdef</RequestId>
</ResponseMetadata>
</GetCallerIdentityResponse>
您可以使用AWS Command Line Interface获取帐户ID,这是一个示例:
$ aws sts get-caller-identity --output text --query Account
121371349383
Initial Answer
这至少可以通过AWS Identity and Access Management (IAM)通过GetUser动作间接实现(可通过getUser()中的AWS SDK for Java获得):
检索有关指定用户的信息,包括用户的路径,GUID和ARN。
如果您未指定用户名,IAM将根据签署请求的AWS Access Key ID隐式确定用户名。
返回的User数据类型(Class User)包含一个Arn元素(getArn()),它是指定用户的Amazon资源名称(ARN)。这在Identifiers for IAM Entities,中进一步详细说明,特别是在ARNs部分,它描述了用户资源类型的格式:
arn:aws:iam::{account_ID}:user/{path/to/user/UserName}
Example: arn:aws:iam::123456789012:user/division_abc/subdivision_xyz/Bob
ElasticTranscoder ListPresets返回包含ARN的数据结构,其中包含AWS账户ID。
与许多其他流行的建议不同,此aws-cli命令适用于基本凭据,IAM用户,IAM角色,实例角色和跨帐户角色假设:
aws elastictranscoder list-presets --query 'Presets[0].Arn' |
cut -d: -f5
当然,您需要获得进行ListPresets API调用的权限,但任何答案都是如此。
一些答案提供了从IAM用户检索AWS账户ID的方法。如果您使用IAM角色的凭据,这些解决方案将生成运行时异常。
在这种情况下,您可以这样做:
// you can get it with @Import(SnsConfiguration::class) for instance
@Autowired
private AWSCredentialsProvider credentialsProvider;
private String resolveAmazonAccountId() {
AmazonIdentityManagement imClient = AmazonIdentityManagementClientBuilder.standard()
.withCredentials(credentialsProvider)
.build();
String roleArn = imClient.getRole(new GetRoleRequest().withRoleName("role name")).getRole().getArn();
// https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-arns
// arn:partition:service:region:account:resource
return roleArn.split(":")[4];
}
这是一个古老的问题,但对于那里的可怜的灵魂 - 基于ARN的答案是我们发现的最正确的答案。调用DescribeInstances时还有一个OwnerId字段,但可能没有实例..
然而,现实有点复杂。有时IAM用户没有权限发出getUser(),然后他获得了AmazonServiceException
getErrorCode() = "AccessDenied"
在这种情况下,ARN是AWS错误消息的一部分:
User: arn:aws:iam::123456789012:user/division_abc/subdivision_xyz/Bob is not authorized to perform:
iam:GetUser on resource: arn:aws:iam::123456789012:user/division_abc/subdivision_xyz/Bob
所以问题更严重:我们需要解析一个自由文本错误消息,然后提取帐号:
try {
... iam.getUser(); ...
} catch (AmazonServiceException e) {
if (e.getErrorCode().compareTo("AccessDenied") == 0) {
String arn = null;
String msg = e.getMessage();
// User: arn:aws:iam::123456789012:user/division_abc/subdivision_xyz/Bob is not authorized to perform: iam:GetUser on resource: arn:aws:iam::123456789012:user/division_abc/subdivision_xyz/Bob
int arnIdx = msg.indexOf("arn:aws");
if (arnIdx != -1) {
int arnSpace = msg.indexOf(" ", arnIdx);
arn = msg.substring(arnIdx, arnSpace);
}
System.out.println("ARN: " + arn);
}
如果您拥有AWS CLI工具,则可以:
aws iam get-user | awk '/arn:aws:/{print $2}'
使用最新的API,可以直接找到用户ID:
BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials("your access key", "your secret key");
AmazonIdentityManagementClient iamClient = new AmazonIdentityManagementClient(basicAWSCredentials);
String userId = iamClient.getUser().getUser().getUserId();
这是使新的STS getCallerIdentity工作(使用Java)的代码:
private String getAccountIDUsingAccessKey(String accessKey, String secretKey) {
AWSSecurityTokenService stsService = AWSSecurityTokenServiceClientBuilder.standard().withCredentials(
new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey))).build();
GetCallerIdentityResult callerIdentity = stsService.getCallerIdentity(new GetCallerIdentityRequest());
return callerIdentity.getAccount();
}
当然,要向@SteffenOpel道具提供所需的线索。
在这里添加它,因为它是“查找aws帐号”的最高结果,并且因为对于部署的应用程序使用密钥而不是IAM角色是不好的做法...
如果您从具有IAM角色的AWS实例运行,则可以执行curl -s http://169.254.169.254/latest/meta-data/iam/info
并从结果的InstanceProfileArn
键获取实例角色的ARN,而不必担心尝试解析异常消息或授予对不需要它们的实例的IAM权限。
然后,您只需解析ARN的帐号。
我做了一个有趣的发现 - 如果你用一个不存在的RoleName调用GetRole,你得到的错误消息包含调用帐户的ARN,所以只需从中解析出帐号。这很好,因为它适用于我能想到的所有情况,即使调用者没有调用GetRole的权限。
这是我收到的错误消息:
User: arn:aws:sts::669916120315:assumed-role/CloudMail_Server/i-31dd19cd is not authorized to perform: iam:GetRole on resource: role _no_such_role_
错误消息的“669916120315”部分是AWS账户ID。
虽然我不认为这是一个理想的场景,但它确实完成了工作。这使用AWSSDK 3.0。
public string GetUserId()
{
AmazonIdentityManagementServiceClient c =
new AmazonIdentityManagementServiceClient();
GetUserRequest request = new GetUserRequest();
GetUserResponse response = c.GetUser(request);
//parse it from the ARN
//should be similar to "arn:aws:iam::111111111111:user/username"
string[] arnParts = response.User.Arn.Split(new char[] { ':' });
return arnParts[4];
}
默认安全组的所有者是“帐户ID”
以上是关于如何从可用的BasicAWSCredentials中推断出AWS账户ID?的主要内容,如果未能解决你的问题,请参考以下文章