使用创建 IAM 策略 Amazon SDK for Java 2.x - Amazon SDK for Java 2.x
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用创建 IAM 策略 Amazon SDK for Java 2.x

IAM 策略生成器 API 是一个库,可用于在 Java 中构建 IAM 策略并将其上传到 Amazon Identity and Access Management (IAM)。

API 不是通过手动组装 JSON 字符串或读取文件来生成 IAM policy,而是提供了一种面向对象的客户端方法来生成 JSON 字符串。当您读取 JSON 格式的现有 IAM 策略时,API 会将其转换为IamPolicy实例进行处理。

IAM Policy 生成器 API 从 SDK 的 2.20.105 版本开始可用,因此请在 Maven 构建文件中使用该版本或更高版本。SDK 的最新版本号在 Maven central 上列出

以下代码段显示了 Maven pom.xml 文件的依赖项代码块示例。该代码块允许您在项目中使用 IAM policy 生成器 API。

<dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>iam-policy-builder</artifactId> <version>2.20.139</version> </dependency>

创建 IamPolicy

本部分显示了如何使用 IAM policy 生成器 API 生成策略的几个示例。

以下每个示例都从 IamPolicy.Builder 开始,然后使用 addStatement 方法添加一条或多条语句。按照这种模式,IamStatement.Builder 提供了向语句添加效果、操作、资源和条件的方法。

示例:创建基于时间的策略

以下示例创建了一个基于身份的策略,该策略允许在两个时间点之间执行 Amazon DynamoDB GetItem 操作。

public String timeBasedPolicyExample() { IamPolicy policy = IamPolicy.builder() .addStatement(b -> b .effect(IamEffect.ALLOW) .addAction("dynamodb:GetItem") .addResource(IamResource.ALL) .addCondition(b1 -> b1 .operator(IamConditionOperator.DATE_GREATER_THAN) .key("aws:CurrentTime") .value("2020-04-01T00:00:00Z")) .addCondition(b1 -> b1 .operator(IamConditionOperator.DATE_LESS_THAN) .key("aws:CurrentTime") .value("2020-06-30T23:59:59Z"))) .build(); // Use an IamPolicyWriter to write out the JSON string to a more readable format. return policy.toJson(IamPolicyWriter.builder() .prettyPrint(true) .build()); }

以上示例中的最后一条语句返回以下 JSON 字符串。

有关此示例的更多信息,请参阅《Amazon Identity and Access Management 用户指南》。

{ "Version" : "2012-10-17", "Statement" : { "Effect" : "Allow", "Action" : "dynamodb:GetItem", "Resource" : "*", "Condition" : { "DateGreaterThan" : { "aws:CurrentTime" : "2020-04-01T00:00:00Z" }, "DateLessThan" : { "aws:CurrentTime" : "2020-06-30T23:59:59Z" } } }

示例:指定多个条件

以下示例演示如何创建基于身份的策略,以允许访问特定 DynamoDB 属性。该政策包含两个条件。

public String multipleConditionsExample() { IamPolicy policy = IamPolicy.builder() .addStatement(b -> b .effect(IamEffect.ALLOW) .addAction("dynamodb:GetItem") .addAction("dynamodb:BatchGetItem") .addAction("dynamodb:Query") .addAction("dynamodb:PutItem") .addAction("dynamodb:UpdateItem") .addAction("dynamodb:DeleteItem") .addAction("dynamodb:BatchWriteItem") .addResource("arn:aws:dynamodb:*:*:table/table-name") .addConditions(IamConditionOperator.STRING_EQUALS.addPrefix("ForAllValues:"), "dynamodb:Attributes", List.of("column-name1", "column-name2", "column-name3")) .addCondition(b1 -> b1.operator(IamConditionOperator.STRING_EQUALS.addSuffix("IfExists")) .key("dynamodb:Select") .value("SPECIFIC_ATTRIBUTES"))) .build(); return policy.toJson(IamPolicyWriter.builder() .prettyPrint(true).build()); }

以上示例中的最后一条语句返回以下 JSON 字符串。

有关此示例的更多信息,请参阅《Amazon Identity and Access Management 用户指南》。

{ "Version" : "2012-10-17", "Statement" : { "Effect" : "Allow", "Action" : [ "dynamodb:GetItem", "dynamodb:BatchGetItem", "dynamodb:Query", "dynamodb:PutItem", "dynamodb:UpdateItem", "dynamodb:DeleteItem", "dynamodb:BatchWriteItem" ], "Resource" : "arn:aws:dynamodb:*:*:table/table-name", "Condition" : { "ForAllValues:StringEquals" : { "dynamodb:Attributes" : [ "column-name1", "column-name2", "column-name3" ] }, "StringEqualsIfExists" : { "dynamodb:Select" : "SPECIFIC_ATTRIBUTES" } } }

示例:指定主体

以下示例演示如何创建基于资源的策略,以拒绝除条件中指定的主体之外的所有主体访问某个桶。

public String specifyPrincipalsExample() { IamPolicy policy = IamPolicy.builder() .addStatement(b -> b .effect(IamEffect.DENY) .addAction("s3:*") .addPrincipal(IamPrincipal.ALL) .addResource("arn:aws:s3:::BUCKETNAME/*") .addResource("arn:aws:s3:::BUCKETNAME") .addCondition(b1 -> b1 .operator(IamConditionOperator.ARN_NOT_EQUALS) .key("aws:PrincipalArn") .value("arn:aws:iam::444455556666:user/user-name"))) .build(); return policy.toJson(IamPolicyWriter.builder() .prettyPrint(true).build()); }

以上示例中的最后一条语句返回以下 JSON 字符串。

有关此示例的更多信息,请参阅《Amazon Identity and Access Management 用户指南》。

{ "Version" : "2012-10-17", "Statement" : { "Effect" : "Deny", "Principal" : "*", "Action" : "s3:*", "Resource" : [ "arn:aws:s3:::BUCKETNAME/*", "arn:aws:s3:::BUCKETNAME" ], "Condition" : { "ArnNotEquals" : { "aws:PrincipalArn" : "arn:aws:iam::444455556666:user/user-name" } } } }

示例:允许跨账户存取。

以下示例说明如何允许其他人将对象上传 Amazon Web Services 账户 到您的存储桶,同时保留所有者对上传对象的完全控制权。

public String allowCrossAccountAccessExample() { IamPolicy policy = IamPolicy.builder() .addStatement(b -> b .effect(IamEffect.ALLOW) .addPrincipal(IamPrincipalType.AWS, "111122223333") .addAction("s3:PutObject") .addResource("arn:aws:s3:::DOC-EXAMPLE-BUCKET/*") .addCondition(b1 -> b1 .operator(IamConditionOperator.STRING_EQUALS) .key("s3:x-amz-acl") .value("bucket-owner-full-control"))) .build(); return policy.toJson(IamPolicyWriter.builder() .prettyPrint(true).build()); }

以上示例中的最后一条语句返回以下 JSON 字符串。

有关此示例的更多信息,请参阅《Amazon Simple Storage Service 用户指南》。

{ "Version" : "2012-10-17", "Statement" : { "Effect" : "Allow", "Principal" : { "AWS" : "111122223333" }, "Action" : "s3:PutObject", "Resource" : "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*", "Condition" : { "StringEquals" : { "s3:x-amz-acl" : "bucket-owner-full-control" } } } }

IamPolicy 与 IAM 配合使用

创建 IamPolicy 实例后,您可以通过 IamClient 来使用 IAM 服务。

以下示例构建了一个策略,允许 IAM 身份向使用 accountID 参数指定的账户中的 DynamoDB 表写入项目。然后,策略会作为 JSON 字符串上传到 IAM。

public String createAndUploadPolicyExample(IamClient iam, String accountID, String policyName) { // Build the policy. IamPolicy policy = IamPolicy.builder() // 'version' defaults to "2012-10-17". .addStatement(IamStatement.builder() .effect(IamEffect.ALLOW) .addAction("dynamodb:PutItem") .addResource("arn:aws:dynamodb:us-east-1:" + accountID + ":table/exampleTableName") .build()) .build(); // Upload the policy. iam.createPolicy(r -> r.policyName(policyName).policyDocument(policy.toJson())); return policy.toJson(IamPolicyWriter.builder().prettyPrint(true).build()); }

下一个示例建立在前一个示例的基础上。该代码下载策略,并通过复制和修改声明将其用作新策略的基础。然后上传新策略。

public String createNewBasedOnExistingPolicyExample(IamClient iam, String accountID, String policyName, String newPolicyName) { String policyArn = "arn:aws:iam::" + accountID + ":policy/" + policyName; GetPolicyResponse getPolicyResponse = iam.getPolicy(r -> r.policyArn(policyArn)); String policyVersion = getPolicyResponse.policy().defaultVersionId(); GetPolicyVersionResponse getPolicyVersionResponse = iam.getPolicyVersion(r -> r.policyArn(policyArn).versionId(policyVersion)); // Create an IamPolicy instance from the JSON string returned from IAM. String decodedPolicy = URLDecoder.decode(getPolicyVersionResponse.policyVersion().document(), StandardCharsets.UTF_8); IamPolicy policy = IamPolicy.fromJson(decodedPolicy); /* All IamPolicy components are immutable, so use the copy method that creates a new instance that can be altered in the same method call. Add the ability to get an item from DynamoDB as an additional action. */ IamStatement newStatement = policy.statements().get(0).copy(s -> s.addAction("dynamodb:GetItem")); // Create a new statement that replaces the original statement. IamPolicy newPolicy = policy.copy(p -> p.statements(Arrays.asList(newStatement))); // Upload the new policy. IAM now has both policies. iam.createPolicy(r -> r.policyName(newPolicyName) .policyDocument(newPolicy.toJson())); return newPolicy.toJson(IamPolicyWriter.builder().prettyPrint(true).build()); }

前面的示例使用了一个 IamClient 参数,它是使用如下所示的代码段创建的。

IamClient iam = IamClient.builder().region(Region.AWS_GLOBAL).build();

这些示例返回以下 JSON 字符串。

First example { "Version" : "2012-10-17", "Statement" : { "Effect" : "Allow", "Action" : "dynamodb:PutItem", "Resource" : "arn:aws:dynamodb:us-east-1:111122223333:table/exampleTableName" } } Second example { "Version" : "2012-10-17", "Statement" : { "Effect" : "Allow", "Action" : [ "dynamodb:PutItem", "dynamodb:GetItem" ], "Resource" : "arn:aws:dynamodb:us-east-1:111122223333:table/exampleTableName" } }