为什么我的 AWS Glue 任务返回 403 访问被拒绝错误?

上次更新日期:2021 年 7 月 21 日

尝试读取/写入 Amazon Simple Storage Service (Amazon S3) 存储桶时,我的 AWS Glue 任务返回 403 访问被拒绝错误。

简短描述

您收到“访问被拒绝”错误通常是由于以下原因之一:

  • AWS Identity and Access Management (IAM) 角色没有访问存储桶所需的权限。
  • Amazon S3 存储桶策略不允许 IAM 角色获得所需的权限。
  • S3 存储桶拥有者不同于对象拥有者。
  • Amazon Virtual Private Cloud (Amazon VPC) 端点策略不包括访问 S3 存储桶所需的权限。
  • 对象由 AWS Key Management Service (AWS KMS) 加密,并且 AWS KMS 策略没有向 IAM 角色授予使用密钥所需的最低权限。
  • S3 存储桶启用了申请方付款
  • 对 S3 存储桶的访问受到 AWS Organizations 服务控制策略的限制。

注意:如果在运行 AWS CLI 命令时遇到错误,请确保您使用的是最新版本的 AWS CLI

解决方法

确保 IAM 角色具有访问 S3 存储桶所需的权限

运行 AWS Glue 任务的 IAM 角色需要访问 S3 存储桶的权限。通过将 IAM 策略附加到 IAM 角色,向 IAM 角色授予所需的权限。

执行以下操作以更新 IAM 角色的存储桶访问权限:

1.    打开 IAM 控制台

2.    打开与 AWS Glue 任务关联并需要访问存储桶的 IAM 角色。

3.    在 IAM 角色的权限选项卡中,展开每个策略以查看其 JSON 策略文档。

4.    在 JSON 策略文档中,搜索包含存储桶名称的策略。然后,确认这些策略是否允许在存储桶上执行正确的 S3 操作。

5.    如果 IAM 角色未授予访问存储桶所需的权限,请添加授予相应权限的策略。例如,以下 IAM 策略授予 IAM 角色将对象 (s3: PutObject) 放入 S3 存储桶 DOC-EXAMPLE-BUCKET 的访问权限:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ExampleStmt",
            "Action": "s3:PutObject",
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
            ]
        }
    ]
}

请务必将策略中的 DOC-EXAMPLE-BUCKET 替换为自己的 S3 存储桶名称。

确保存储桶策略向 IAM 角色授予所需的权限

查看存储桶策略以了解以下内容:

  • 任何明确拒绝 IAM 角色访问存储桶的语句
  • 任何可能限制 IAM 角色访问权的缺失权限和条件

执行以下操作以查看和修改存储桶策略,从而向 IAM 角色授予所需的访问权限:

  1. 打开 Amazon S3 控制台
  2. 从导航窗格中选择存储桶
  3. 从存储桶列表中,打开您要检查的存储桶。
  4. 选择权限,然后向下滚动到存储桶策略部分。
  5. 查看存储桶策略是否有任何拒绝角色对存储桶的访问权限的语句。
  6. 修改存储桶策略以编辑或删除任何拒绝 IAM 角色对存储桶的访问权限的语句。

有关示例存储桶策略,请参阅存储桶策略示例

确保 S3 存储桶拥有者有权访问对象

默认情况下,S3 对象归上传此对象的 AWS 账户所有。即使存储桶由另一个账户拥有,也是如此。如果其他账户可以将对象上传到您的存储桶,则查看您的用户/角色无法访问的对象是属于哪个账户。通过运行 GetObjectAcl 命令可检查对象拥有者。

如果来自其他账户的 IAM 用户/角色将对象上传到 S3 存储桶,请设置 S3 对象所有权。然后,添加一个存储桶策略,该策略要求使用 bucket-owner-full-control 访问控制列表 (ACL) 上传对象。使用 bucket-owner-full-control ACL 上传该对象时,添加存储桶策略会自动将该对象的拥有者更改为存储桶拥有者。有关更多信息,请参阅当其他 AWS 账户将对象上传到我的 Amazon S3 存储桶时,我如何才能要求他们授予我这些对象的完全控制权?

确保 Amazon VPC 终端节点策略允许对 S3 存储桶执行必要的操作

确保 VPC 终端节点策略包括在满足以下两个条件时访问 S3 存储桶和对象所需的权限:

  • 您的 AWS Glue 任务将对象读取或写入 S3 中。
  • 使用 VPC 终端节点将连接路由到 S3。

例如,以下 VPC 终端节点策略仅允许访问存储桶 DOC-EXAMPLE-BUCKET。如果您的存储桶未在策略中作为允许的资源列出,则用户/角色将无法通过 VPC 终端节点访问您的存储桶。

{
    "Statement": [
        {
            "Sid": "Access-to-specific-bucket-only",
            "Principal": "*",
            "Action": [
                "s3:PutObject"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
        }
    ]
}

请务必将策略中的DOC-EXAMPLE-BUCKET 替换为您的 S3 存储桶的名称。

如果用户/角色使用 ACL 上传对象,则必须更新 VPC 终端节点策略以授予对 PutObjectAcl 操作的访问权限。例如:

{
    "Statement": [
        {
            "Sid": "Access-to-specific-bucket-only",
            "Principal": "*",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
        }
    ]
}

请确保 AWS KMS 密钥策略允许访问 IAM 角色

如果您的数据提取、转换和加载 (ETL) 任务读取或将加密数据写入 Amazon S3,那么请确保以下事项:

  • IAM 角色的策略包括 AWS KMS 操作所需的权限。
  • AWS KMS 密钥的策略包括 IAM 角色所需的权限。

在 IAM 角色的策略中包含以下权限,以允许执行必要的 AWS KMS 操作:

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": [
            "kms:Decrypt",
            "kms:Encrypt",
            "kms:GenerateDataKey"
        ],
        "Resource": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"
    }
}

请务必用自己选择的 ARN 替换策略中的 ARN。

有关更多信息,请参阅在 AWS Glue 中设置加密

查看 KMS 密钥策略以验证策略是否允许访问 AWS Glue 任务的角色。有关密钥策略的更多信息,请参阅在 AWS KMS 中使用密钥策略

如果存储桶启用了申请方付款,请务必包括申请方付款标头

如果 S3 存储桶启用了申请方付款,则 AWS Glue 任务向存储桶发出的所有请求都必须包含申请方付款标头。默认情况下,对 Amazon S3 的 AWS Glue 请求不包括“申请方付款”标头。如果没有该标头,则“申请方付款”存储桶的 API 调用将失败并发出“访问被拒绝”异常。要将“申请方付款”标头添加到 ETL 脚本中,请在 GlueContext 变量或 Apache Spark 会话变量上使用 hadoopConfiguration().set() 包括 fs.s3.useRequesterPaysHeader

有关更多信息,请参阅如何从 AWS Glue、Amazon EMR 或 Athena 中访问 S3 申请方付款存储桶?

确保 AWS Organizations 服务控制策略允许访问 S3

如果您使用的是 AWS Organizations,则检查服务控制策略以确保允许访问 Amazon S3。例如,以下策略明确拒绝访问 Amazon S3 并导致“访问被拒绝”错误。

{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Deny",
 "Action": "s3:*",
 "Resource": "*"
 }
 ]
}

有关更多信息,请参阅启用组织中的所有功能


这篇文章对您有帮助吗?


您是否需要账单或技术支持?