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-1 と field-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 スキーマでディレクティブが欠けている。