38

似乎在文档中的任何地方都找不到这个;如果我使用 BasicAWSCredentials 进行身份验证,例如 AccessKeyId 和 SecretKey,是否可以获得 AWS 账户 ID?

4

12 回答 12

35

更新

AWS 刚刚通过引入专用 STS API 操作GetCallerIdentity默默地解决了这个长期存在的差距,它返回有关其凭证用于调用 API 的 IAM 身份的详细信息,包括 AWS 账户 ID - 有一些示例响应,例如:

<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 命令​​行界面仅获取账户 ID,这是一个示例:

$ aws sts get-caller-identity --output text --query Account
121371349383

初步答案

这至少可以通过AWS Identity and Access Management (IAM)通过GetUser操作(可通过AWS SDK for Java中的getUser()获得)间接实现:

检索有关指定用户的信息,包括用户的路径、GUID 和 ARN。

如果您不指定用户名,IAM 会根据签署请求的 AWS 访问密钥 ID 隐式确定用户名。

返回的User数据类型 ( Class User ) 包含一个Arn元素 ( getArn() ),它是指定 user 的 Amazon 资源名称 (ARN)。这在Identifiers for IAM Entities 中有更详细的说明,特别是在ARNs部分中,它描述了User Resource Type的格式:

arn:aws:iam::{account_ID}:user/{path/to/user/UserName}

Example: arn:aws:iam::123456789012:user/division_abc/subdivision_xyz/Bob
于 2012-04-17T20:45:28.767 回答
10

这是一个老问题,但对于那些可怜的人来说——基于 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);
}
于 2013-08-08T10:55:37.330 回答
10

如果您拥有 AWS CLI 工具,则可以:

aws iam get-user | awk '/arn:aws:/{print $2}'
于 2015-01-06T16:35:10.257 回答
9

这是使较新的 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 提供所需线索的道具。

于 2017-02-22T05:01:36.517 回答
8

使用最新的 API 可以直接找到用户 ID:

BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials("your access key", "your secret key");
AmazonIdentityManagementClient iamClient = new AmazonIdentityManagementClient(basicAWSCredentials);
String userId = iamClient.getUser().getUser().getUserId();
于 2013-11-24T12:08:01.207 回答
5

在此处添加此内容,因为它是“查找 aws 帐号”的最高 SO 结果,并且因为无论如何使用密钥而不是 IAM 角色来部署应用程序都是不好的做法......

如果您从具有 IAM 角色的 AWS 实例运行,您可以curl -s http://169.254.169.254/latest/meta-data/iam/info从结果的键中获取实例角色的 ARN InstanceProfileArn,而不必担心尝试解析异常消息或授予 IAM 权限到不需要它们的实例。

然后,您只需解析帐号的 ARN。

于 2014-12-10T17:10:07.150 回答
2

我做了一个有趣的发现——如果你用不存在的 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。

于 2015-03-19T13:20:58.660 回答
2

While I don't consider this an ideal scenario, it does get the job done. This uses the 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];
}
于 2015-09-11T02:47:25.000 回答
1

使用 AWS Java SDK v2:

public String getAccountId(AwsCredentialsProvider awsAuth, Region awsRegion) {
    StsClient stsClient = getClient(awsAuth, awsRegion);

    GetCallerIdentityRequest request = GetCallerIdentityRequest
        .builder()
        .build();

    GetCallerIdentityResponse response = stsClient.getCallerIdentity(request);
    return response.account();
}
public StsClient getClient(AwsCredentialsProvider awsAuth, Region awsRegion) {
        return StsClient
                .builder()
                .credentialsProvider(awsAuth)
                .region(awsRegion)
                .build();
}
于 2020-02-17T12:46:47.210 回答
0

默认安全组的所有者是“帐户 ID”

于 2015-06-01T16:33:26.100 回答
0

一些答案提供了一种从 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];
}
于 2019-03-16T01:04:00.300 回答
0

ElasticTranscoder ListPresets返回一个数据结构,其中包含包含 AWS 账户 ID 的 ARN。

与许多其他流行建议不同,此 aws-cli 命令适用于基本凭证、IAM 用户、IAM 角色、实例角色和跨账户角色假设:

aws elastictranscoder list-presets --query 'Presets[0].Arn' | 
  cut -d: -f5

当然,您需要获得调用 ListPresets API 的权限,但任何答案都是如此。

于 2015-11-04T22:34:12.677 回答