在 AWS AppSync 中執行 GraphQL 請求時,如何對「未經授權」錯誤進行疑難排解?

上次更新日期:2022 年 7 月 20 日

當我使用 AWS AppSync 執行 GraphQL 請求時,我收到「未經授權」錯誤訊息。如何對這些錯誤進行疑難排解?

簡短描述

按照回應所傳回的 HTTP 狀態碼,我們可以分辨出兩類未經授權錯誤:

  • 401 未經授權:憑證遺失或無效,導致 AWS AppSync 或授權模式拒絕請求。
  • 200 OK 回應 未授授權 類型錯誤訊息:解析器或其他層級出現問題,導致請求遭到拒絕。

若要判斷未經授權錯誤的原因,請嘗試在 Web 瀏覽器中重現問題。然後,使用瀏覽器的網絡工具擷取 HTTP 請求和回應訊息,再分析訊息以判斷發生錯誤的位置。如要離線分析訊息,請將訊息儲存在 HTTP 封存 (HAR) 檔案中

解決方案

401 未經授權回應

如果是 401 未經授權 回應,請檢查傳送 GraphQL 承載資料的網路請求,以確認:

  • Authorization (授權) 或 x-api-key 標頭存在,並包含作業或欄位所需的授權模式正確憑證。如果標頭缺少了正確的憑證,授權模式將會拒絕請求。
  • 如果使用 JSON Web 權杖 (JWT),授權標頭不包含 “Bearer” (承載者) 一詞 (來自 GitHub 網站)。
  • JWT 來自正確的 Amazon Cognito 使用者集區或 OIDC 提供者。
  • 憑證有效且未過期。

200 OK 回應

若要取得有關 200 OK 回應中 未經授權 錯誤原因的詳細資訊,請在 AWS AppSync API 上啟動 Amazon CloudWatch Logs。疑難排解的最佳實務是將欄位層級記錄設定為 All (全部),並列出詳細內容。

如果收到 200 OK 回應且錯誤類型為 未經授權,而且 出現 未經授權在類型 Y 上存取 X 的訊息,代表 Apache Velocity 範本語言 (VTL) 解析器映射範本中的邏輯拒絕了該請求。若要解決此問題,請針對您使用的授權模式完成下列疑難排解步驟。

Amazon Cognito 和 OIDC 授權

將用戶的權杖宣告 (例如群組、email_verified 以及用戶端 ID 或受眾) 與 VTL 解析器映射範本中的授權檢查進行比較。您可以使用第三方工具 jwt.io (來自 AuthO) 來檢查權杖宣告。如果您使用 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,請確認結構描述上的授權規則允許建立、讀取、更新或刪除作業

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 Logs 或加入偵錯陳述式,以驗證判斷使用者授權的邏輯流程

使用多種授權模式

如果您的 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 的結構描述缺少了指令。

此文章是否有幫助?


您是否需要帳單或技術支援?