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

2 分的閱讀內容
0

當我使用 AWS AppSync 執行 GraphQL 請求時,我會收到「未授權」錯誤。

簡短說明

根據回應中傳回的 HTTP 狀態代碼定義,有兩種類型的未授權錯誤:

  • 401 未授權: AWS AppSync 或授權模式拒絕請求,因為憑證遺失或無效。
  • 200 確定回應有未授權類型錯誤: 由於在解析器層級或更高層級發生問題,請求被拒絕。

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

解決方法

401 未授權的回應

對於 ** 401 未授權**回應,請檢查傳送 GraphQL 承載的網路請求以確認:

  • 存在 授權x-api-key 標頭,並包含作業或欄位所需授權模式的正確憑證。如果標頭沒有正確的憑證,則授權模式會拒絕請求。
  • 對於 JSON Web 權杖 (JWT),請參閱 GitHub 網站上的 Authorization header doesn't include the text "Bearer" (授權標頭不包含 "Bearer" 文字)。
  • JWT 來自正確的 Amazon Cognito 使用者集區或 OpenID Connect (OIDC) 提供者。
  • 憑證有效且未過期。

200 OK 回應

如要取得有關造成 200 OK 回應的未授權錯誤原因的詳細資訊,請在 AWS AppSync API 上開啟 Amazon CloudWatch Logs。最佳做法是將欄位層級記錄設為全部,並包括詳細內容。

Apache Velocity 範本語言 (VTL) 解析器對應範本中的邏輯會拒絕收到 200 OK 回應但出現未授權錯誤類型和 Not Authorized to access X on type Y (未授權存取 Y 類型的 X) 訊息的請求。如要解決此問題,請對您使用的授權模式完成下列疑難排解步驟。

Amazon 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) 使用者或角色的原則。如要驗證在動作區塊是否為使用者存取的每個欄位授予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 授權

  • 檢查您以 Lambda 函數程式碼編寫用來發出 isAuthorized 的自訂邏輯,以確保其設定為 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 官方已更新 1 個月前