AWS AppSync で GraphQL リクエストを実行する際の、"Unauthorized" エラーをトラブルシューティングする方法を教えてください。

所要時間2分
0

AWS AppSync で GraphQL リクエストを実行すると、"Unauthorized" エラーが発生します。

簡単な説明

応答で返される HTTP ステータスコードで定義される、Unauthorized エラーには次の 2 種類があります。

  • 401 Unauthorized: 認証情報が欠けているか無効であるため、リクエストは AWS AppSync または認証モードによって拒否されました。
  • Unauthorized タイプのエラーを含む 200 OK 応答: リゾルバーレベルまたは、それよりも上位の問題が原因で、リクエストは拒否されました。

Unauthorized エラーの原因を特定するために、ウェブブラウザで問題を再現します。次に、ブラウザのネットワークツールを使用して HTTP リクエストメッセージと応答メッセージをキャプチャします。メッセージを分析して、エラーが発生した場所を判断します。オフラインで分析するために、メッセージを HTTP アーカイブ (HAR) ファイルに保存します。

解決策

401 Unauthorized 応答

401 Unauthorized 応答の場合、GraphQL ペイロードを送信するネットワークリクエストで次のことを確認します。

  • Authorization または x-api-key ヘッダーがあり、操作またはフィールドに必要な認証モードの正しい認証情報が含まれている。ヘッダーに正しい認証情報がない場合、認証モードによりリクエストは拒否されます。
  • JSON ウェブトークン (JWT) の場合は、GitHub のウェブサイトで「Authorization ヘッダーに "Bearer" というテキストが含まれていない」を参照してください。
  • JWT は、適切な Amazon Cognito ユーザープールまたは OpenID Connect (OIDC) プロバイダーのものである。
  • 認証情報が有効で、有効期限内である。

200 OK 応答

200 OK 応答での Unauthorized エラーの原因に関する詳細を得るには、AWS AppSync API に対して Amazon CloudWatch ログを有効にします。フィールドレベルのログ記録を [すべて] に設定し、詳細な内容を含めるようにするのがベストプラクティスです。

リクエストがエラータイプ Unauthorized および、タイプ Y で X へのアクセスは許可されていません というメッセージを含む 200 OK 応答を受信した場合は、Apache Velocity Template Language (VTL) リゾルバーマッピングテンプレートのロジックにより拒否されています。この問題を解決するには、使用している認証モードに応じて、次のトラブルシューティング手順を実行します。

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 認証

  • 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 スキーマでディレクティブが欠けている。
コメントはありません

関連するコンテンツ