我的 Amazon EMR 应用程序遇到 HTTP 403 "Access Denied" AmazonS3Exception 错误

上次更新时间:2019 年 11 月 21 日

当我提交应用程序到 Amazon EMR 集群时,应用程序遇到 HTTP 403 "Access Denied" AmazonS3Exception 错误:

java.io.IOException: com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: 8B28722038047BAA; S3 Extended Request ID: puwS77OKgMrvjd30/EY4CWlC/AuhOOSNsxfI8xQJXMd20c7sCq4ljjVKsX4AwS7iuo92C9m+GWY=), S3 Extended Request ID: puwS77OKgMrvjd30/EY4CWlC/AuhOOSNsxfI8xQJXMd20c7sCq4ljjVKsX4AwS7iuo92C9m+GWY=

简短描述

此错误表示因为以下某项遇到问题,应用程序在尝试执行 Amazon Simple Storage Service (Amazon S3) 操作时失败:

  • 您的应用程序代码中指定的凭证或角色
  • 附加于 Amazon Elastic Compute Cloud (Amazon EC2) 实例配置文件角色的策略
  • Amazon S3 VPC 终端节点策略
  • Amazon S3 源和目标存储桶策略

解决方法

在 EMR 集群的主节点上运行以下命令。使用您的 Amazon S3 路径替换 s3://awsexamplebucket/abc/

aws s3 ls s3://awsexamplebucket/abc/

如果此命令成功,说明您的应用程序代码中指定的凭证或角色导致 "Access Denied" 错误。这些凭证或角色必须拥有访问 Amazon S3 路径的权限。

如果此命令失败,检查以下各项以解决 "Access Denied" 错误:

检查 Amazon EC2 实例配置文件角色的策略

在默认情况下,应用程序会从 Amazon EC2 实例配置文件的 AWS Identity and Access Management (IAM) 角色继承 Amazon S3 访问权限。附加于此角色的 IAM 策略必须允许对源和目标存储桶执行所需的 Amazon S3 操作。

如果您使用 EMRFS 角色映射,则您的应用程序会从 IAM 角色为提交该应用程序的用户继承 Amazon S3 权限。此 IAM 用户必须有允许对源和目标存储桶执行所需 Amazon S3 操作的 IAM 策略。

检查 Amazon S3 VPC 终端节点策略

如果 EMR 集群的子网路由表有指向 Amazon S3 VPC 终端节点的路由,确认终端节点策略允许所需的 Amazon S3 操作。您可以使用 AWS 命令行界面 (AWS CLI) 或 Amazon VPC 控制台来检查与修改终端节点策略。

AWS CLI:

运行以下命令以检查终端节点策略。使用您的 VPC ID 替换 vpce-9f28e4f6

aws ec2 describe-vpc-endpoints --vpc-endpoint-ids "vpce-9f28e4f6"

如有必要,运行以下命令来上传修改后的终端节点策略。在示例中,替换 VPC ID 和 JSON 文件路径。

aws ec2 modify-vpc-endpoint --vpc-endpoint-id "vpce-9f28e4f6" --policy-document file://policy.json

Amazon VPC 控制台:

1.    打开 Amazon VPC 控制台

2.    在导航窗格中,选择终端节点

3.    选择 Amazon S3 终端节点(位于 EMR 集群的子网路由表),然后选择策略选项卡来检查终端节点策略。

4.    要添加所需的 Amazon S3 操作,选择编辑策略

检查 S3 存储桶策略

存储桶策略指定允许或拒绝委托人的哪些操作。源和目标存储桶的存储桶策略必须允许 EC2 实例配置文件角色或映射的 IAM 角色执行所需的 Amazon S3 操作。您可以使用 AWS CLI 或 Amazon S3 控制台来检查与修改存储桶策略。

AWS CLI:

运行以下命令来检查存储桶策略。使用源或目标存储桶的名称替换 awsexamplebucket

aws s3api get-bucket-policy --bucket awsexamplebucket

如有必要,运行以下命令来上传修改后的存储桶策略。在示例中,替换存储桶名称和 JSON 文件路径。

aws s3api put-bucket-policy --bucket awsexamplebucket --policy file://policy.json

Amazon S3 控制台:

1.    打开 Amazon S3 控制台

2.    选择存储桶。

3.    选择权限选项卡。

4.    选择存储桶策略以检查与修改存储桶策略。

访问另一个账户中的 S3 存储桶

如果您的应用程序访问另一个 AWS 账户的 S3 存储桶,账户拥有者必须允许您在存储桶策略上的 IAM 角色。例如,以下存储桶策略将为 emr-account 中的所有 IAM 角色和用户提供 s3://awsexamplebucket/myfolder/ 的全部访问权限。

{
    "Id": "MyCustomPolicy",
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowRootAndHomeListingOfCompanyBucket",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::emr-account:root"
                ]
            },
            "Action": [
                "s3:ListBucket"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::awsexamplebucket"
            ],
            "Condition": {
                "StringEquals": {
                    "s3:prefix": [
                        "",
                        "myfolder/"
                    ],
                    "s3:delimiter": [
                        "/"
                    ]
                }
            }
        },
        {
            "Sid": "AllowListingOfUserFolder",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::emr-account:root"
                ]
            },
            "Action": [
                "s3:ListBucket"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::awsexamplebucket"
            ],
            "Condition": {
                "StringLike": {
                    "s3:prefix": [
                        "myfolder/*"
                    ]
                }
            }
        },
        {
            "Sid": "AllowAllS3ActionsInUserFolder",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::emr-account:root"
                ]
            },
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::awsexamplebucket/myfolder/*",
                "arn:aws:s3:::awsexamplebucket/myfolder*"
            ]
        }
    ]
}