Amazon Cognito ユーザー認証に成功・失敗したログの確認方法

2021.12.15

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Amazon Cognito のユーザー認証機能を利用しています。ユーザー認証に成功・失敗したログをAWS側で確認するにはどこをみればよいのでしょうか?

ユーザープールに対してAWS CLIを利用して Cognito の API を使った ユーザー認証を行い認証成功・失敗ログを例にAWS側に記録されているログを紹介します。

結論

ユーザー名の情報を確認したければCognitoのアドバンスドセキュリティ有効化をご検討ください。CloudTrailにはユーザー名ではなくユーザーIDが記録されます。

  • CognitoのAPIを利用した操作の認証ログはCloudTrailに記録される
  • CloudTrailのログにはユーザー名、パスワードなどの秘匿情報は記録されない
    • ユーザー名は記録されないがユーザーIDにあたるUserSubはCloudTrailに記録される
  • Cognitoのアドバンスドセキュリティを有効化するとユーザーイベント履歴が利用可能になる
  • Cognitoのユーザーイベント履歴はユーザー名毎に認証に成功、失敗のログが記録される

ユーザーイベント履歴参考

検証環境

ユーザープール(test-user-pool)を作成し、テストユーザ(test-user)を作成しました。

アプリケーションクライアント(test-app-client)を作成しています。

アプリケーションクライアント詳細

$ aws --version
aws-cli/2.4.4 Python/3.9.9 Darwin/20.6.0 source/x86_64 prompt/off

認証テストコマンド

クライアントサイドからユーザープールへ認証することを想定してInitiateAuthオペレーションをAWS CLIから実行します。

テストユーザに対して正しいパスワードを入力し認証成功させます。

サインイン成功コマンド

$ aws cognito-idp initiate-auth \
        --client-id 23pj82arn6rvpmbc30pil6vah \
        --auth-flow USER_PASSWORD_AUTH \
        -auth-parameters "USERNAME=test-user,PASSWORD=Password258461378"

認証成功するとアクセストークンなどのレスポンスがあります。

レスポンス

{
    "ChallengeParameters": {},
    "AuthenticationResult": {
        "AccessToken": "aaa",
        "ExpiresIn": 3600,
        "TokenType": "Bearer",
        "RefreshToken": "bbb",
        "IdToken": "ccc"
    }
}

誤ったパスワードを入力し認証失敗させます。

サインイン失敗コマンド

$ aws cognito-idp initiate-auth \
        --client-id 23pj82arn6rvpmbc30pil6vah \
        --auth-flow USER_PASSWORD_AUTH \
        -auth-parameters "USERNAME=test-user,PASSWORD=aaaaaaaa"

リクエスト元のクライアントにはエラーメッセージが返ってきます。しかし、クライアントサイドでログを記録するのは難しいといったときはAWS側のログを確認したくなります。

レスポンス

An error occurred (NotAuthorizedException) when calling the InitiateAuth operation: Incorrect username or password.

標準の認証ログ確認(CloudTrail)

ユーザー認証成功・失敗のログはCloudTrailに記録されます。CloudWatch Logsではないんですね。

AWS CloudTrail – CloudTrail では、Amazon Cognito コンソールからの API コール、および Amazon Cognito API オペレーションへのコードコールをキャプチャできます。例えば、ユーザーが認証すると、CloudTrail はリクエストの IP アドレス、リクエストの実行者、および実行日時などの詳細を記録できます。

CloudTrailを確認

イベント履歴から以下のどちらかでフィルタすると確認しやすいです。今回はInitiateAuthでフィルタしています。

  • イベント名: InitiateAuth
  • イベントソース: cognito-idp.amazonaws.com

エラーコードを列に表示させておくと多少わかりやすくなります。エラーコードに理由が書いてなければ認証に成功、何か書いてあれば認証に失敗したログなので見比べやすくなります。

CloudTrailのドキュメントには以下の注釈があります。ユーザー名は記録されないが、ユーザーIDにあたるUserSubから特定は可能とのことです。

ユーザー固有のリクエストについて、Amazon Cognito は CloudTrail ログに UserSub を記録しますが、UserName は記録しません。ListUsers API を呼び出し、sub のフィルターを使用することで、所定の UserSub のユーザーを見つけることができます。

CloudTrail 内の Amazon Cognito 情報 - Amazon Cognito

認証成功ログ

  • responseElements:に値が入っているのが認証成功ログの特徴
  • リクエスト時のユーザー名、パスワードはセキュリティ上の理由で隠されています
  • レスポンスのトークン情報も同様にセキュリティ上の理由で隠されています
  • subにユーザーIDが記録されている
{
    "eventVersion": "1.08",
    "userIdentity": {
        "type": "Unknown",
        "principalId": "Anonymous"
    },
    "eventTime": "2021-12-14T13:51:45Z",
    "eventSource": "cognito-idp.amazonaws.com",
    "eventName": "InitiateAuth",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "240b:13:91a0:7d00:3c7f:3c4:e5d8:1451",
    "userAgent": "aws-cli/2.4.4 Python/3.9.9 Darwin/20.6.0 source/x86_64 prompt/off command/cognito-idp.initiate-auth",
    "requestParameters": {
        "authFlow": "USER_PASSWORD_AUTH",
        "authParameters": "HIDDEN_DUE_TO_SECURITY_REASONS",
        "clientId": "23pj82arn6rvpmbc30pil6vah"
    },
    "responseElements": {
        "challengeParameters": {},
        "authenticationResult": {
            "accessToken": "HIDDEN_DUE_TO_SECURITY_REASONS",
            "expiresIn": 3600,
            "tokenType": "Bearer",
            "refreshToken": "HIDDEN_DUE_TO_SECURITY_REASONS",
            "idToken": "HIDDEN_DUE_TO_SECURITY_REASONS"
        }
    },
    "additionalEventData": {
        "sub": "9f0a3592-a9e8-4fb8-a2d1-7562a438f58d"
    },
    "requestID": "45fc20d3-ac80-4111-af05-edd6b4ddbd2e",
    "eventID": "01c2a9a7-13e3-4788-ad06-c659a3956b35",
    "readOnly": false,
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "123456789012",
    "eventCategory": "Management"
}

認証失敗ログ

  • errorCode:キーが追加される
  • errorMessage:キーが追加される
  • responseElements:は空になる
  • subにユーザーIDが記録されている
{
    "eventVersion": "1.08",
    "userIdentity": {
        "type": "Unknown",
        "principalId": "Anonymous"
    },
    "eventTime": "2021-12-14T13:51:38Z",
    "eventSource": "cognito-idp.amazonaws.com",
    "eventName": "InitiateAuth",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "240b:13:91a0:7d00:3c7f:3c4:e5d8:1451",
    "userAgent": "aws-cli/2.4.4 Python/3.9.9 Darwin/20.6.0 source/x86_64 prompt/off command/cognito-idp.initiate-auth",
    "errorCode": "NotAuthorizedException",
    "errorMessage": "Incorrect username or password.",
    "requestParameters": {
        "authFlow": "USER_PASSWORD_AUTH",
        "authParameters": "HIDDEN_DUE_TO_SECURITY_REASONS",
        "clientId": "23pj82arn6rvpmbc30pil6vah"
    },
    "responseElements": null,
    "additionalEventData": {
        "sub": "9f0a3592-a9e8-4fb8-a2d1-7562a438f58d"
    },
    "requestID": "d8424039-4064-420b-a603-035b045193ae",
    "eventID": "71250fd8-f78c-4fdd-bc77-1d5775ba89b9",
    "readOnly": false,
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "123456789012",
    "eventCategory": "Management"
}

CloudTrailログのまとめ

  • 認証成功・失敗はイベントレコードを確認すれば判断できる
  • ユーザー名、パスワードなどのセンシティブな情報はCloudTrailには残らない
  • ユーザーIDは記録されるためユーザーを特定することはできる

ユーザー名をキーに認証に成功、失敗したかを確認したいときはCloudTrailのログをみてもすぐには判断つかない

2023/3/30追記
ユーザーIDからユーザー名を確認するには以下の記事が参考になるかと思います。

アドバンスドセキュリティ機能を有効化

追加課金のオプション機能にアドバンスドセキュリティがあります。主にユーザーアカウントの保護機能が提供されます。

有効化したユーザープールに対して以下のセキュリティ機能が追加されます。

認証成功・失敗ログとなにか関係があるの?と思うかもしれませんが、ユーザーイベント履歴が確認できるようになります!

ユーザー毎に認証成功か失敗を確認できます。こちらの履歴はCognitoで2年間保持されます。CloudTrailのログではユーザー情報は載ってこなかったので、ユーザー情報を確認したいなら有効化する価値があります。

AWS CLI

ユーザーイベント履歴はAWS CLIからでも確認できます。

aws cognito-idp admin-list-user-auth-events \
       --user-pool-id ap-northeast-1_xxxxxxx \
       --username test-user

レスポンス一部抜粋

{
    "AuthEvents": [
        {
            "EventId": "45fc20d3-ac80-4111-af05-edd6b4ddbd2e",
            "EventType": "SignIn",
            "CreationDate": "2021-12-14T22:51:44.889000+09:00",
            "EventResponse": "Pass",
            "EventRisk": {
                "RiskDecision": "NoRisk",
                "CompromisedCredentialsDetected": false
            },
            "ChallengeResponses": [
                {
                    "ChallengeName": "Password",
                    "ChallengeResponse": "Success"
                }
            ],
            "EventContextData": {
                "IpAddress": "240b:13:91a0:1111:3c7f:1111:e5d8:1111",
                "DeviceName": "Other, Other",
                "City": "Sapporo",
                "Country": "Japan"
            }
        },
        {
            "EventId": "d8424039-4064-420b-a603-035b045193ae",
            "EventType": "SignIn",
            "CreationDate": "2021-12-14T22:51:38.104000+09:00",
            "EventResponse": "Fail",
            "EventRisk": {
                "RiskDecision": "NoRisk",
                "CompromisedCredentialsDetected": false
            },
            "ChallengeResponses": [
                {
                    "ChallengeName": "Password",
                    "ChallengeResponse": "Failure"
                }
            ],
            "EventContextData": {
                "IpAddress": "240b:13:91a0:1111:3c7f:1111:e5d8:1111",
                "DeviceName": "Other, Other",
                "City": "Sapporo",
                "Country": "Japan"
            }
        }
    ]
}

ユーザーイベント履歴まとめ

  • アドバンスドセキュリティを有効化すると利用できる機能
  • ユーザー名毎に認証成功・失敗を確認できる
  • AWS CLIからユーザーイベント履歴を確認することもできる

まとめ

ユーザー名の情報を確認したければCognitoのアドバンスドセキュリティ有効化をご検討ください。CloudTrailにはユーザー名ではなくユーザーIDが記録されます。

  • CognitoのAPIを利用した操作の認証ログはCloudTrailに記録される
  • CloudTrailのログにはユーザー名、パスワードなどの秘匿情報は記録されない
    • ユーザー名は記録されないがユーザーIDにあたるUserSubはCloudTrailに記録される
  • Cognitoのアドバンスドセキュリティを有効化するとユーザーイベント履歴が利用可能になる
  • Cognitoのユーザーイベント履歴はユーザー名毎に認証に成功、失敗のログが記録される

おわりに

ログの出力例をドキュメントから確認できなかったので残しました。時間がなくAWS CLIからの認証テストになりました。本当は認証用Webページ作って試したかったですが、その辺の技術には疎いのでサクッとできそうになく断念しました。急ぎ検証で使いたいときもあるので勉強したいなと思いました。

ユーザープールのユーザー認証検証環境は以下を参考に40分ほどで作成できました。API Gateayも作成し認証したトークンでアクセスできるかもテストはしたのですが、認証成功失敗ログ採取するだけの環境ならCognitoだけ作ればよいので時間短縮できたと思います。

参考