如何对在 AWS AppSync 中运行 GraphQL 请求时出现的“Unauthorized”(未授权)错误进行故障排除?

2 分钟阅读
0

当我使用 AWS AppSync 运行 GraphQL 请求时,我收到了“Unauthorized”(未授权)错误。

简短描述

响应中返回的 HTTP 状态代码定义了两种未授权错误:

  • 401 Unauthorized(401 未授权): 由于凭证缺失或无效,请求被 AWS AppSync 或授权模式拒绝。
  • 200 OK 响应,显示 Unauthorized(未授权)类型错误: 由于解析程序级别或者超出解析程序级别存在问题,请求被拒绝。

要确定出现未授权错误的原因,请尝试在 Web 浏览器中重现该问题。然后,使用浏览器的网络工具捕获 HTTP 请求和响应消息。分析消息以确定错误发生的位置。要进行离线分析,请以 HTTP 存档 (HAR) 文件格式保存消息

解决方法

401 Unauthorized(401 未授权)响应

对于 401 Unauthorized(401 未授权)响应,请检查发送 GraphQL 有效载荷的网络请求,以确认:

  • 存在 Authorizationx-api-key 标头,其中包含操作或字段所需的授权模式的正确凭证。如果标头未包含正确的凭证,则授权模式会拒绝该请求。
  • 对于 JSON Web 令牌 (JWT),请参阅 GitHub 网站上的 Authorization 标头不包含文本“Bearer”
  • JWT 来自正确的 Amazon Cognito 用户池或 OpenID Connect (OIDC) 提供商。
  • 凭证有效且未过期。

200 OK 响应

要详细了解导致 200 OK 响应出现 Unauthorized(未授权)错误的原因,请在 AWS AppSync API 上启用 Amazon CloudWatch Logs。最佳做法是将字段级别日志记录设置为 All,并包含详细内容。

Apache Velocity 模板语言 (VTL) 解析器映射模板中的逻辑会拒绝接收错误类型为 Unauthorized(未授权),以及消息为 Not Authorized to access X on type Y(未获得访问 Y 类别 X 的授权)的 200 OK 响应的请求。要解决此问题,请针对您使用的授权模式完成以下故障排除步骤。

mazon Cognito 和 OIDC 授权

将用户的令牌声明(例如组、email_verified、客户端 ID 或受众)与 VTL 解析器映射模板中的授权检查进行比较。您可以使用 AuthO 网站上的第三方工具 jwt.io 来检查令牌声明。如果您使用的是 AWS Amplify,请验证令牌声明是否支持模型架构类型的授权规则要求。例如,以下用于 Amplify 的解析器映射模板会检查从 AWS AppSync 执行的初步授权检查中传递的数据。

#if( $util.authType() == "User Pool Authorization" )
  #if( !$isAuthorized )
    #set( $staticGroupRoles = [{"claim":"cognito:groups","entity":"Admin","allowedFields":xxxxx,yyyyy}] )
    #foreach( $groupRole in $staticGroupRoles )
      #set( $groupsInToken =
 $util.defaultIfNull($ctx.identity.claims.get($groupRole.claim), []) )
      #if( $groupsInToken.contains($groupRole.entity) )
        #if( $groupRole.isAuthorizedOnAllFields )
          #set( $isAuthorized = true )
          #break
        #else
          $util.qr($allowedFields.addAll($groupRole.allowedFields))
        #end
      #end
    #end
  #end
#end

此外,如果您使用的是 Amplify,请验证架构上的授权规则是否允许执行创建、读取、更新或删除操作。有关详细信息,请参阅 Amplify Docs 网站上的自定义授权规则

IAM 授权

查看适用于签署 AWS AppSync 请求的AWS Identity and Access Management (IAM) 用户或角色的策略。要验证是否在 Action(操作)块中为用户访问的每个字段授予 appsync:GraphQL,请运行以下命令:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "appsync:GraphQL"
      ],
      "Resource": [
        "arn:aws:appsync:us-east-1:111122223333:apis/graphql-api-id/types/Query/fields/field-1",
        "arn:aws:appsync:us-east-1:111122223333:apis/graphql-api-id/types/Mutation/fields/field-2"
      ]
    }
  ]
}

**注意:**请将 graphql-api-id 替换为您的 GraphQL API 的 ID,将 field-1field-2 替换为您的字段

如果您使用 Amplify 生成解析器映射模板,请验证以下内容:

  • 颁发 IAM 凭证使用的角色会话名称等于 CognitoIdentityCredentials
  • IAM 凭证与 Amplify 生成的授权或未授权角色相同。

如果角色会话名称与字符串不匹配,则会拒绝对该字段或操作的访问。

Lambda 授权

  • 检查您在发出 isAuthorized 的 Lambda 函数代码中编写的自定义逻辑,确保其设置为 true
  • 确保 deniedFields 数组不包含请求的字段或操作。
  • 检查 CloudWatch 日志或添加调试语句,以验证用于确定用户授权的逻辑流

使用多种授权模式

当您的 AWS AppSync API 具有多种授权模式时,该 API 将使用设置的默认授权模式。对于需要使用其他授权模式之一的类型或字段,还必须为该模式设置授权指令。有关详细信息,请参阅为 AWS AppSync GraphQL API 使用多种授权类型。例如,AWS AppSync API 将 API_KEY 设置为默认授权模式,将 AMAZON_COGNITO_USER_POOLS 设置为其他授权模式。如果要同时使用这两种模式,则必须设置 @aws_api_key@aws_cognito_user_pools 授权指令。

type Post @aws_api_key @aws_cognito_user_pools {
 id: ID!
 author: String
 title: String
}

**注意:**默认 API_KEY 授权模式会拒绝请求,原因如下:

  • 在请求标头中发送了 Amazon Cognito JWT。
  • GraphQL 架构中缺少这些指令。
AWS 官方
AWS 官方已更新 5 个月前