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

2021.12.15

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

ユーザープールに対してAWS CLIからユーザー認証を行い認証成功・失敗ログを例にAWS側に記録されているログを紹介します。

結論

ユーザー毎の情報を確認したければCognitoのアドバンスドセキュリティ有効化をご検討ください。

  • 標準の認証ログはCloudTrailに記録される
  • Cognitoのアドバンスドセキュリティを有効化するとユーザーイベント履歴が利用可能になる
  • CloudTrailのログにはユーザー名、パスワードなどの秘匿情報は記録されない
    • ユーザー毎の認証成功・失敗を確認できないのがCloudTrail
  • ユーザーイベント履歴はユーザー毎に認証に成功、失敗のログが記録される
    • ユーザー毎の認証成功・失敗を確認できるのが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

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

認証成功ログ

  • responseElements:に値が入っているのが認証成功ログの特徴
  • リクエスト時のユーザー名、パスワードはセキュリティ上の理由で隠されています
  • レスポンスのトークン情報も同様にセキュリティ上の理由で隠されています
{
    "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:は空になる
{
    "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には残らない

どのユーザーが認証に成功、失敗したかはCloudTrailのログからは判断つかない

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

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

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

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

ユーザー毎に認証成功か失敗を確認できます。こちらの履歴は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からユーザーイベント履歴を確認することもできる

まとめ

ユーザー毎の情報を確認したければアドバンスドセキュリティ有効化をご検討ください。

  • CloudTrailにユーザー認証成功・失敗のログが記録される
    • ユーザー名、パスワードなどの秘匿情報は記録されない
  • アドバンスドセキュリティを有効化するとユーザーイベント履歴を確認できる
    • ユーザー毎の認証成功・失敗を確認できる

おわりに

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

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

参考