选择您的 Cookie 首选项

我们使用必要 Cookie 和类似工具提供我们的网站和服务。我们使用性能 Cookie 收集匿名统计数据,以便我们可以了解客户如何使用我们的网站并进行改进。必要 Cookie 无法停用,但您可以单击“自定义”或“拒绝”来拒绝性能 Cookie。

如果您同意,AWS 和经批准的第三方还将使用 Cookie 提供有用的网站功能、记住您的首选项并显示相关内容,包括相关广告。要接受或拒绝所有非必要 Cookie,请单击“接受”或“拒绝”。要做出更详细的选择,请单击“自定义”。

权限和 AWS CDK

聚焦模式
权限和 AWS CDK - AWS Cloud Development Kit (AWS CDK) v2

这是 AWS CDK v2 开发者指南。旧版 CDK v1 于 2022 年 6 月 1 日进入维护阶段,并于 2023 年 6 月 1 日终止支持。

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

这是 AWS CDK v2 开发者指南。旧版 CDK v1 于 2022 年 6 月 1 日进入维护阶段,并于 2023 年 6 月 1 日终止支持。

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

C AWS onstruct Library 使用一些常见的、广泛实施的习语来管理访问和权限。IAM 模块可为您提供使用这些习语所需的工具。

AWS CDK AWS CloudFormation 用于部署更改。每个部署都涉及启动 AWS CloudFormation 部署的参与者(开发人员或自动化系统)。在此过程中,参与者将假设一个或多个 IAM 身份(用户或角色),并可选择将角色传递给 AWS CloudFormation。

如果您使用用户身份 AWS IAM Identity Center 进行身份验证,则单点登录提供商会提供短期会话证书,授权您充当预定义的 IAM 角色。要了解如何通过 IAM Identity Center 身份验证 AWS CDK 获取 AWS 证书,请参阅AWS SDKs 和工具参考指南中的了解 IAM 身份中心身份验证

主体

IAM 委托人是一个经过身份验证的 AWS 实体,代表可以调用的用户、服务或应用程序 AWS APIs。C AWS onstruct Library 支持以多种灵活的方式指定委托人,以授予他们访问您的 AWS 资源的权限。

在安全上下文中,“主体”一词专门指经过身份验证的实体,例如用户。组和角色之类的对象并不代表用户(以及其他经过身份验证的实体),而是间接识别他们的身份以授予权限。

例如,如果您创建一个 IAM 组,则可以向该组(以及其成员)授予对 Amazon RDS 表的写入权限。但是,组本身不是主体,因为它不代表单个实体(而且,您无法登录组)。

在 CDK 的 IAM 库中,直接或间接识别主体身份的类实现了 IPrincipal 接口,从而允许这些对象在访问策略中互换使用。但是,从安全意义上讲,并非所有对象都是主体。这些对象包括:

  1. IAM 资源,例如 RoleUser、和 Group

  2. 服务主体 (new iam.ServicePrincipal('service.amazonaws.com'))

  3. 联合身份验证主体 (new iam.FederatedPrincipal('cognito-identity.amazonaws.com'))

  4. 账户主体 (new iam.AccountPrincipal('0123456789012')))

  5. 规范用户主体 (new iam.CanonicalUserPrincipal('79a59d[...]7ef2be'))

  6. AWS Organizations 校长 () new iam.OrganizationPrincipal('org-id')

  7. 任意 ARN 主体 (new iam.ArnPrincipal(res.arn))

  8. 信任多个主体的 iam.CompositePrincipal(principal1, principal2, ...)

授权

表示可以访问的资源(例如 Amazon S3 存储桶或 Amazon DynamoDB 表)的每个构造都有向其他实体授予访问权限的方法。所有这些方法的名称都以 grant 开头。

例如,Amazon S3 存储桶具有方法 grantReadgrantReadWrite(Python:grant_readgrant_read_write),用于分别启用实体对存储桶的读取和读/写访问权限。该实体不必确切知道执行这些操作需要哪些 Amazon S3 IAM 权限。

授予方法的第一个参数始终为类型IGrantable。此接口表示可以被授予权限的实体。也就是说,它表示具有角色的资源,例如 IAM 对象 RoleUserGroup

也可以向其他实体授予权限。例如,在本主题的后面部分,我们将介绍如何向 CodeBuild项目授予对 Amazon S3 存储桶的访问权限。通常,关联角色是通过被授予访问权限的实体的 role 属性获得的。

使用执行角色的资源(例如 lambda.Function)也会实现 IGrantable,因此您可以直接向其授予访问权限,而不必向其角色授予访问权限。例如,如果 bucket 是 Amazon S3 存储桶,并且 function 是 Lambda 函数,则以下代码会向函数授予对存储桶的读取访问权限。

TypeScript
bucket.grantRead(function);
JavaScript
bucket.grantRead(function);
Python
bucket.grant_read(function)
Java
bucket.grantRead(function);
C#
bucket.GrantRead(function);
bucket.grantRead(function);

有时,必须在部署堆栈时应用权限。其中一种情况是您向 AWS CloudFormation 自定义资源授予对其他资源的访问权限时。该自定义资源将在部署期间被调用,因此它在部署时必须具有指定的权限。

另一种情况是当服务验证您传递给它的角色是否应用了正确的策略时。(许多 AWS 服务通过这种方式确保您不会忘记设置策略。) 在这种情况下,如果权限应用得太晚,部署可能会失败。

要在创建其他资源之前强制应用 grant 要授予的权限,您可以向 grant 本身添加依赖项,如下所示。尽管通常会丢弃 grant 方法的返回值,但实际上每个 grant 方法都会返回一个 iam.Grant 对象。

TypeScript
const grant = bucket.grantRead(lambda); const custom = new CustomResource(...); custom.node.addDependency(grant);
JavaScript
const grant = bucket.grantRead(lambda); const custom = new CustomResource(...); custom.node.addDependency(grant);
Python
grant = bucket.grant_read(function) custom = CustomResource(...) custom.node.add_dependency(grant)
Java
Grant grant = bucket.grantRead(function); CustomResource custom = new CustomResource(...); custom.node.addDependency(grant);
C#
var grant = bucket.GrantRead(function); var custom = new CustomResource(...); custom.node.AddDependency(grant);
const grant = bucket.grantRead(lambda); const custom = new CustomResource(...); custom.node.addDependency(grant);

角色

IAM 程序包包含一个代表 IAM 角色的 Role 构造。以下代码创建了一个新角色,即信任 Amazon EC2 服务。

TypeScript
import * as iam from 'aws-cdk-lib/aws-iam'; const role = new iam.Role(this, 'Role', { assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'), // required });
JavaScript
const iam = require('aws-cdk-lib/aws-iam'); const role = new iam.Role(this, 'Role', { assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com') // required });
Python
import aws_cdk.aws_iam as iam role = iam.Role(self, "Role", assumed_by=iam.ServicePrincipal("ec2.amazonaws.com")) # required
Java
import software.amazon.awscdk.services.iam.Role; import software.amazon.awscdk.services.iam.ServicePrincipal; Role role = Role.Builder.create(this, "Role") .assumedBy(new ServicePrincipal("ec2.amazonaws.com")).build();
C#
using Amazon.CDK.AWS.IAM; var role = new Role(this, "Role", new RoleProps { AssumedBy = new ServicePrincipal("ec2.amazonaws.com"), // required });
import * as iam from 'aws-cdk-lib/aws-iam'; const role = new iam.Role(this, 'Role', { assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'), // required });

您可以通过调用角色的 addToPolicy 的方法(Python:add_to_policy),传入定义要添加的规则的 PolicyStatement 来为该角色添加权限。该语句将添加到角色的默认策略中;如果角色没有策略,则会创建一个。

在授权服务为 AWS CodeBuild的条件下,以下示例会针对资源 bucketotherRole(Python:other_role)上的 ec2:SomeActions3:AnotherAction 操作,向角色添加 Deny 策略语句。

TypeScript
role.addToPolicy(new iam.PolicyStatement({ effect: iam.Effect.DENY, resources: [bucket.bucketArn, otherRole.roleArn], actions: ['ec2:SomeAction', 's3:AnotherAction'], conditions: {StringEquals: { 'ec2:AuthorizedService': 'codebuild.amazonaws.com', }}}));
JavaScript
role.addToPolicy(new iam.PolicyStatement({ effect: iam.Effect.DENY, resources: [bucket.bucketArn, otherRole.roleArn], actions: ['ec2:SomeAction', 's3:AnotherAction'], conditions: {StringEquals: { 'ec2:AuthorizedService': 'codebuild.amazonaws.com' }}}));
Python
role.add_to_policy(iam.PolicyStatement( effect=iam.Effect.DENY, resources=[bucket.bucket_arn, other_role.role_arn], actions=["ec2:SomeAction", "s3:AnotherAction"], conditions={"StringEquals": { "ec2:AuthorizedService": "codebuild.amazonaws.com"}} ))
Java
role.addToPolicy(PolicyStatement.Builder.create() .effect(Effect.DENY) .resources(Arrays.asList(bucket.getBucketArn(), otherRole.getRoleArn())) .actions(Arrays.asList("ec2:SomeAction", "s3:AnotherAction")) .conditions(java.util.Map.of( // Map.of requires Java 9 or later "StringEquals", java.util.Map.of( "ec2:AuthorizedService", "codebuild.amazonaws.com"))) .build());
C#
role.AddToPolicy(new PolicyStatement(new PolicyStatementProps { Effect = Effect.DENY, Resources = new string[] { bucket.BucketArn, otherRole.RoleArn }, Actions = new string[] { "ec2:SomeAction", "s3:AnotherAction" }, Conditions = new Dictionary<string, object> { ["StringEquals"] = new Dictionary<string, string> { ["ec2:AuthorizedService"] = "codebuild.amazonaws.com" } } }));
role.addToPolicy(new iam.PolicyStatement({ effect: iam.Effect.DENY, resources: [bucket.bucketArn, otherRole.roleArn], actions: ['ec2:SomeAction', 's3:AnotherAction'], conditions: {StringEquals: { 'ec2:AuthorizedService': 'codebuild.amazonaws.com', }}}));

在前面的示例中,我们使用 addToPolicy(Python:add_to_policy)调用创建了一个新的 PolicyStatement 内联策略。您也可以传入现有的或您修改过的策略语句。该PolicyStatement对象有多种添加委托人、资源、条件和操作的方法

如果要使用的构造需要角色才能正常运行,您可以执行以下操作之一:

  • 在实例化构造对象时传入现有角色。

  • 让构造为您创建一个新角色,并信任相应的服务主体。以下示例使用这样的构造: CodeBuild 项目。

TypeScript
import * as codebuild from 'aws-cdk-lib/aws-codebuild'; // imagine roleOrUndefined is a function that might return a Role object // under some conditions, and undefined under other conditions const someRole: iam.IRole | undefined = roleOrUndefined(); const project = new codebuild.Project(this, 'Project', { // if someRole is undefined, the Project creates a new default role, // trusting the codebuild.amazonaws.com service principal role: someRole, });
JavaScript
const codebuild = require('aws-cdk-lib/aws-codebuild'); // imagine roleOrUndefined is a function that might return a Role object // under some conditions, and undefined under other conditions const someRole = roleOrUndefined(); const project = new codebuild.Project(this, 'Project', { // if someRole is undefined, the Project creates a new default role, // trusting the codebuild.amazonaws.com service principal role: someRole });
Python
import aws_cdk.aws_codebuild as codebuild # imagine role_or_none is a function that might return a Role object # under some conditions, and None under other conditions some_role = role_or_none(); project = codebuild.Project(self, "Project", # if role is None, the Project creates a new default role, # trusting the codebuild.amazonaws.com service principal role=some_role)
Java
import software.amazon.awscdk.services.iam.Role; import software.amazon.awscdk.services.codebuild.Project; // imagine roleOrNull is a function that might return a Role object // under some conditions, and null under other conditions Role someRole = roleOrNull(); // if someRole is null, the Project creates a new default role, // trusting the codebuild.amazonaws.com service principal Project project = Project.Builder.create(this, "Project") .role(someRole).build();
C#
using Amazon.CDK.AWS.CodeBuild; // imagine roleOrNull is a function that might return a Role object // under some conditions, and null under other conditions var someRole = roleOrNull(); // if someRole is null, the Project creates a new default role, // trusting the codebuild.amazonaws.com service principal var project = new Project(this, "Project", new ProjectProps { Role = someRole });
import * as codebuild from 'aws-cdk-lib/aws-codebuild'; // imagine roleOrUndefined is a function that might return a Role object // under some conditions, and undefined under other conditions const someRole: iam.IRole | undefined = roleOrUndefined(); const project = new codebuild.Project(this, 'Project', { // if someRole is undefined, the Project creates a new default role, // trusting the codebuild.amazonaws.com service principal role: someRole, });

创建对象后,角色(无论是传入的角色还是构造创建的默认角色)即可作为属性 role 使用。但是,此属性不可用于外部资源。因此,这些构造支持 addToRolePolicy(Python:add_to_role_policy)方法。

如果构造是外部资源,则该方法不执行任何操作,否则它会调用 role 属性的 addToPolicy(Python:add_to_policy)方法。这为您省去了显式处理未定义案例的麻烦。

以下示例说明了:

TypeScript
// project is imported into the CDK application const project = codebuild.Project.fromProjectName(this, 'Project', 'ProjectName'); // project is imported, so project.role is undefined, and this call has no effect project.addToRolePolicy(new iam.PolicyStatement({ effect: iam.Effect.ALLOW, // ... and so on defining the policy }));
JavaScript
// project is imported into the CDK application const project = codebuild.Project.fromProjectName(this, 'Project', 'ProjectName'); // project is imported, so project.role is undefined, and this call has no effect project.addToRolePolicy(new iam.PolicyStatement({ effect: iam.Effect.ALLOW // ... and so on defining the policy }));
Python
# project is imported into the CDK application project = codebuild.Project.from_project_name(self, 'Project', 'ProjectName') # project is imported, so project.role is undefined, and this call has no effect project.add_to_role_policy(iam.PolicyStatement( effect=iam.Effect.ALLOW, # ... and so on defining the policy )
Java
// project is imported into the CDK application Project project = Project.fromProjectName(this, "Project", "ProjectName"); // project is imported, so project.getRole() is null, and this call has no effect project.addToRolePolicy(PolicyStatement.Builder.create() .effect(Effect.ALLOW) // .. and so on defining the policy .build();
C#
// project is imported into the CDK application var project = Project.FromProjectName(this, "Project", "ProjectName"); // project is imported, so project.role is null, and this call has no effect project.AddToRolePolicy(new PolicyStatement(new PolicyStatementProps { Effect = Effect.ALLOW, // ... and so on defining the policy }));
// project is imported into the CDK application const project = codebuild.Project.fromProjectName(this, 'Project', 'ProjectName'); // project is imported, so project.role is undefined, and this call has no effect project.addToRolePolicy(new iam.PolicyStatement({ effect: iam.Effect.ALLOW, // ... and so on defining the policy }));

资源策略

中的 AWS一些资源(例如 Amazon S3 存储桶和 IAM 角色)也有资源策略。这些构造支持 addToResourcePolicy 方法(Python:add_to_resource_policy),它将 PolicyStatement 作为其参数。添加到资源策略的每条策略语句都必须指定至少一个主体。

在以下示例中,Amazon S3 存储桶 bucket 会向自身授予包含 s3:SomeAction 权限的角色。

TypeScript
bucket.addToResourcePolicy(new iam.PolicyStatement({ effect: iam.Effect.ALLOW, actions: ['s3:SomeAction'], resources: [bucket.bucketArn], principals: [role] }));
JavaScript
bucket.addToResourcePolicy(new iam.PolicyStatement({ effect: iam.Effect.ALLOW, actions: ['s3:SomeAction'], resources: [bucket.bucketArn], principals: [role] }));
Python
bucket.add_to_resource_policy(iam.PolicyStatement( effect=iam.Effect.ALLOW, actions=["s3:SomeAction"], resources=[bucket.bucket_arn], principals=role))
Java
bucket.addToResourcePolicy(PolicyStatement.Builder.create() .effect(Effect.ALLOW) .actions(Arrays.asList("s3:SomeAction")) .resources(Arrays.asList(bucket.getBucketArn())) .principals(Arrays.asList(role)) .build());
C#
bucket.AddToResourcePolicy(new PolicyStatement(new PolicyStatementProps { Effect = Effect.ALLOW, Actions = new string[] { "s3:SomeAction" }, Resources = new string[] { bucket.BucketArn }, Principals = new IPrincipal[] { role } }));
bucket.addToResourcePolicy(new iam.PolicyStatement({ effect: iam.Effect.ALLOW, actions: ['s3:SomeAction'], resources: [bucket.bucketArn], principals: [role] }));

使用外部 IAM 对象

如果您在应用程序之外定义了 IAM 用户、委托人、群组或角色,则可以在 AWS CDK AWS CDK 应用程序中使用该 IAM 对象。为此,请使用对象的 ARN 或名称创建对其的引用。(使用用户、组和角色的名称。) 然后,返回的引用可用于授予权限或构造策略语句,如前所述。

可以使用以下方法以类似方式使用策略(包括托管策略)。您可以在任何需要 IAM 策略的位置使用对这些对象的引用。

注意

与所有对外部 AWS 资源的引用一样,您无法在 CDK 应用程序中修改外部 IAM 对象。

本页内容

下一主题:

上下文值

上一主题:

资产
隐私网站条款Cookie 首选项
© 2025, Amazon Web Services, Inc. 或其附属公司。保留所有权利。