当我在 Amazon Athena 中运行查询时,为什么会出现 "Access Denied"(拒绝访问)错误?

上次更新日期:2021 年 5 月 19 日

我在运行 Amazon Athena 查询时,收到 "Access Denied"(拒绝访问)错误。

简短描述

您收到 "Access Denied"(拒绝访问)错误通常是由于以下原因:

  • AWS Identity and Access Management (IAM) 用户没有以下一个或多个权限:
    • 读取源数据存储桶。
    • 将结果写入查询结果存储桶。
  • Amazon Simple Storage Service (Amazon S3) 存储桶策略不允许 IAM 用户获得所需的权限。
  • 对象拥有者不同于 Amazon S3 存储桶拥有者。
  • 您无权访问用于读取或写入加密数据的 AWS Key Management Service (AWS KMS) 密钥。
  • AWS Glue 数据目录策略不允许访问 IAM 用户。

解决方法

要排查 "Access Denied"(拒绝访问)错误,请确认以下各项。

确保 IAM 用户具有访问源数据存储桶和查询结果存储桶所需的权限

如果您无权访问源数据存储桶,则会收到类似以下内容的错误:

Your query has the following errors:com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: 72VA5FB0ASWCQFPD; S3 Extended Request ID: cykX1CZ/KfxpL/h8/DOQoCBJ88qFGYqt6J52Jqh87qBfyN8c2P2azRiYjjJE1HL7i0Mg9xxxxxx=; Proxy: null), S3 Extended Request ID: cykX1CZ/KfxpL/h8/DOQoCBJ88qFGYqt6J52Jqh87qBfyN8c2P2azRiYjjJE1HL7i0Mg9xxxxxx= (Path: s3://my-athena-source-bucket/athena_data.csv)

如果您无权访问查询结果存储桶,则会收到类似以下内容的错误:

Your query has the following errors:Access denied when writing output to url: s3://my-athena-result-bucket/Unsaved/2021/05/07/example_query_ID.csv . Please ensure you are allowed to access the S3 bucket. If you are encrypting query results with KMS key, please ensure you are allowed to access your KMS key

运行查询的 IAM 用户需要对源数据存储桶和查询结果存储桶的访问权限。通过将 IAM 策略附加到 IAM 用户/角色,向 IAM 用户授予所需的权限。以下 IAM 策略允许源数据存储桶和查询结果存储桶的最低权限:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::my-athena-source-bucket"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::my-athena-source-bucket/data/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads",
                "s3:AbortMultipartUpload",
                "s3:PutObject",
                "s3:ListMultipartUploadParts"
            ],
            "Resource": [
                "arn:aws:s3:::my-athena-result-bucket",
                "arn:aws:s3:::my-athena-result-bucket/*"
            ]
        }
    ]
}

请务必在此示例策略中替换以下内容:

  • my-athena-source-bucket 替换为源数据存储桶的名称
  • my-athena-source-bucket/data/ 替换为源数据位置
  • my-athena-result-bucket 替换为查询结果存储桶的名称

如需完整的策略列表,请参阅用户访问管理策略

将 Amazon S3 存储桶策略附加到跨账户查询所需的权限

如果您的 Athena 表和 S3 存储桶位于同一账户中,则无需附加 S3 存储桶策略。但是,如果您确实有 S3 存储桶策略,请确保它们将所需的 S3 操作授予 IAM 用户/角色。如果您的 Athena 表和 S3 存储桶位于不同的账户中,则需要附加将所需访问权限授予 IAM 用户的 S3 存储桶策略。

您可以在账户 B 中附加类似以下内容的 S3 存储桶策略,以便在账户 A 中将访问权限授予给 IAM 用户 athena_user。此示例策略明确允许 IAM 用户访问账户 B 中的 S3 存储桶 my-athena-source-bucket

{
    "Version": "2012-10-17",
    "Id": "Policy1620692934647",
    "Statement": [
        {
            "Sid": "Stmt1620692932186",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::1111222233334444:user/athena_user"
            },
            "Action": [
                "s3:*"                
            ],
            "Resource": [
                "arn:aws:s3:::my-athena-source-bucket",
                "arn:aws:s3:::my-athena-source-bucket/data/*"
            ]
        }
    ]
}

请务必在上述策略中替换以下内容:

  • my-athena-source-bucket 替换为源数据存储桶的名称
  • my-athena-source-bucket/data/ 替换为源数据位置
  • 1111222233334444 替换为账户 A 的账户 ID
  • athena_user 替换为账户 A 中 IAM 用户的名称。

要在账户 A 中将存储桶的访问权限授予给所有用户,请将 Principal 密钥替换为指定 root 的密钥(例如:arn:aws:iam::1111222233334444:roo)。

注意:上述策略允许对 my-athena-source-bucket 执行所有 S3 操作。您可以根据 S3 存储桶是源存储桶还是查询结果存储桶来更新 S3 操作。有关更多信息,请参阅在 Athena 中对 Amazon S3 存储桶的跨账户访问中的存储桶策略或 IAM 用户策略部分。

确认 S3 存储桶策略不包括明确拒绝访问账户 A 或其 IAM 用户的语句。此外,请确保您的策略不包含可能拒绝请求的条件。有关更多信息,请参阅如何对来自 Amazon S3 的 403 访问被拒绝错误执行故障排查? 要定义 S3 存储桶的最低特权权限,请参阅如何为 AWS 服务调用的操作定义最低特权权限

更新您的 AWS KMS 密钥策略

如果您的源数据已加密,或者您的 Athena 查询使用 AWS KMS 密钥写入加密结果,请确保以下内容:

  • IAM 用户的策略允许必要的 AWS KMS 操作。
  • AWS KMS 密钥的策略允许用户访问。

以下是 AWS KMS 密钥策略的示例,它允许对账户 ID 1111222233334444 中的所有用户执行所有 KMS 操作:

{
  "Sid": "Enable IAM policies",
  "Effect": "Allow",
  "Principal": {
    "AWS": "arn:aws:iam::1111222233334444:root"
   },
  "Action": "kms:*",
  "Resource": "*"
}

请务必根据您的使用案例更新此策略。有关更多信息,请参阅在 AWS KMS 中使用密钥策略Amazon S3 中加密数据的权限

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

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

如果 S3 存储桶拥有者和对象拥有者不同,则对象拥有者可以授予您对对象的完全控制权。对象拥有者可以通过使用 bucket-owner-full-control 参数运行 PutObjectAcl 命令来实现这一点。要将对象的所有权更改为拥有 S3 存储桶的账户,请从存储桶的账户中运行 AWS 命令行界面 (AWS CLI) 命令 cp,将对象复制到自身。

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

有关更多信息,请参阅为何我无法访问由其他 AWS 账户上传到我的 Amazon S3 存储桶的对象?

验证 AWS Glue 数据目录策略是否允许访问 IAM 用户/角色

如果您有现有的 AWS Glue 数据目录策略,请确保该策略允许访问 IAM 用户/角色。例如,如果您的数据目录中有以下策略,则 IAM 用户 athena_user 将被拒绝访问数据目录:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Principal": {
                "AWS": [
                    "arn:aws:iam::1111222233334444:user/athena_user"
                ]
            },
            "Effect": "Deny",
            "Action": [
                "glue:*"
            ],
            "Resource": [
                "arn:aws:glue:us-east-1:1111222233334444:*"
            ]
        }
    ]
}

有关策略示例,请参阅 AWS Glue 基于资源的访问控制策略示例

使用数据目录中的上述策略,用户运行的 Athena 查询可能会失败,并出现以下错误:

Insufficient permissions to execute the query. User: arn:aws:iam:: 1111222233334444:user/athena_user is not authorized to perform: glue:GetTable on resource: arn:aws:glue:us-east-1:1111222233334444:database/doc_example_database with an explicit deny Query Id: example_query_ID

此外,请确保运行查询的 IAM 用户/角色具有访问 AWS Glue 资源所需的权限。有关所需 AWS Glue 权限的完整列表,请参阅 AmazonAthenaFullAccess 托管策略。确保数据目录资源策略不会拒绝所需的 AWS Glue 操作。有关更多信息,请参阅在 AWS Glue 数据目录中对数据库和表的精细访问


这篇文章对您有帮助吗?


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