如何从可用的BasicAWSCredentials中推断出AWS账户ID?

37 java amazon-web-services

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

Ste*_*pel 34

更新

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>
Run Code Online (Sandbox Code Playgroud)

您可以使用AWS命令行界面仅获取帐户ID,这是一个示例:

$ aws sts get-caller-identity --output text --query Account
121371349383
Run Code Online (Sandbox Code Playgroud)

初步答复

这至少可以通过AWS身份和访问管理(IAM)通过GetUser操作(可通过AWS SDK for Java中的getUser()获得)间接实现:

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

如果您未指定用户名,IAM将根据签署请求的AWS Access Key ID隐式确定用户名.

返回的用户数据类型(类用户)包含一个Arn元素(getArn()),它是指定用户Amazon资源名称(ARN).这在IAM实体的​​标识符中进一步详细说明,特别是在ARN部分中,它描述了用户资源类型的格式:

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

Example: arn:aws:iam::123456789012:user/division_abc/subdivision_xyz/Bob
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,如果您在IAM角色下运行EC2实例,则无论您的权限如何,GetUser都将无效,因为该上下文中没有IAM用户. (3认同)

小智 10

这是一个古老的问题,但对于那里的可怜的灵魂 - 基于ARN的答案是我们找到的最正确的答案.调用DescribeInstances时还有一个OwnerId字段,但可能没有实例..

然而,现实有点复杂.有时IAM用户没有权限发出getUser(),然后他获得了AmazonServiceException

getErrorCode() = "AccessDenied"
Run Code Online (Sandbox Code Playgroud)

在这种情况下,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
Run Code Online (Sandbox Code Playgroud)

所以问题更严重:我们需要解析一个自由文本错误消息,然后提取帐号:

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);
}
Run Code Online (Sandbox Code Playgroud)


AXE*_*abs 10

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

aws iam get-user | awk '/arn:aws:/{print $2}'
Run Code Online (Sandbox Code Playgroud)


Mic*_*obi 8

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

BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials("your access key", "your secret key");
AmazonIdentityManagementClient iamClient = new AmazonIdentityManagementClient(basicAWSCredentials);
String userId = iamClient.getUser().getUser().getUserId();
Run Code Online (Sandbox Code Playgroud)

  • 对于IAM用户,它会返回您的访问密钥ID而不是帐号.这样做的优点是可以区分帐户,但无法识别全局帐户(从而无法识别可能的资源空间).我们真的需要两者. (4认同)

Rya*_*ton 7

这是使新的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();
}
Run Code Online (Sandbox Code Playgroud)

当然,要向@SteffenOpel道具提供所需的线索.


Jos*_*ock 5

在这里添加它,因为它是"查找aws帐号"的最高结果,并且因为对于部署的应用程序使用密钥而不是IAM角色是不好的做法...

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

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