Cognitoが提供する認証機能を手を動かしながら理解

Cognitoは「認証」「許可」「ユーザー管理」などの機能を提供しています。様々な認証のユースケースがあるため、ドキュメント内容が多く、とっつきにくい部分があります。ここでは、実際に動作確認しながらCognitoが提供する主要機能を見ていきます。

用語

動作確認すること

今回、動作確認した内容です。

ユーザープールの動作確認

IDプールの動作確認

ユーザープールの動作確認

[管理画面] ユーザープールを作成

696-aws-cognito_userpool-1.png

ユーザプールの管理をクリックします。

696-aws-cognito_userpool-2.png

プール名を入力します。

今回は細かい設定をせずに、デフォルトのまま動作確認をします。なので、デフォルトを確認するをクリックします。

696-aws-cognito_userpool-3.png

デフォルトの設定が表示されています。

プールの作成をクリックします。

696-aws-cognito_userpool-memo-1.png

プールIDをメモしておきます。後述の動作確認で利用します。

[管理画面] アプリクライアントを作成

696-aws-cognito_userpool-4.png

1. サイドメニューのアプリクラインアントを選択します。

2. アプリクライアント名を入力します。

3. 後述の動作確認にて、ADMIN_NO_SRP_AUTHの認証フローを利用します。そのためADMIN_NO_SRP_AUTHにチェックを入れています。

4. アプリクライアントの作成をクリックします。

696-aws-cognito_userpool-memo-2.png

アプリクライアントIDをメモしておきます。後述の動作確認で利用します。

[AWS CLI] ユーザー生成

admin-create-userで管理者としてユーザーを生成できます。

aws cognito-idp admin-create-user \
--profile プロファイル名 \
--user-pool-id ap-northeast-1_xxxxxxxxx \
--username ユーザー名 \
--message-action SUPPRESS \
--temporary-password パスワードポリシーを満たすパスワード

wakuwaku_tarou というユーザーを生成してみます。

$ aws cognito-idp admin-create-user \
> --profile xxxxxxxxx \
> --user-pool-id ap-northeast-1_xxxxxxxxx \
> --username wakuwaku_tarou \
> --message-action SUPPRESS \
> --temporary-password xX-123456
{
    "User": {
        "Username": "wakuwaku_tarou",
        "Attributes": [
            {
                "Name": "sub",
                "Value": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
            }
        ],
        "UserCreateDate": 1563610822.209,
        "UserLastModifiedDate": 1563610822.209,
        "Enabled": true,
        "UserStatus": "FORCE_CHANGE_PASSWORD"
    }
}
696-aws-cognito_userpool-cli-1.png

管理画面からもユーザーが生成されたことを確認できます。

ステータスがFORCE_CHANGE_PASSWORDになっています。

[AWS CLI] ユーザー認証

admin-initiate-authで認証します。

aws cognito-idp admin-initiate-auth \
--profile プロファイル名 \
--user-pool-id ap-northeast-1_xxxxxxxxx \
--client-id xxxxxxxxxxxxxxxxxxxxxxxxxx \
--auth-flow ADMIN_NO_SRP_AUTH \
--auth-parameters USERNAME=wakuwaku_tarou,PASSWORD=xX-123456
$ aws cognito-idp admin-initiate-auth \
> --profile xxxxxxxxx \
> --user-pool-id ap-northeast-1_xxxxxxxxx \
> --client-id xxxxxxxxxxxxxxxxxxxxxxxxxx \
> --auth-flow ADMIN_NO_SRP_AUTH \
> --auth-parameters USERNAME=wakuwaku_tarou,PASSWORD=xX-123456
{
    "ChallengeName": "NEW_PASSWORD_REQUIRED",
    "Session": "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "ChallengeParameters": {
        "USER_ID_FOR_SRP": "wakuwaku_tarou",
        "requiredAttributes": "[\"userAttributes.email\"]",
        "userAttributes": "{\"email\":\"\"}"
    }
}

NEW_PASSWORD_REQUIRED のため、まだトークンを取得できません。代わりに Session が表示されています。

[AWS CLI] 初期パスワード変更

先ほど取得した Session を利用して初期パスワードを変更します。admin-respond-to-auth-challengeを利用します。

aws cognito-idp admin-respond-to-auth-challenge \
--profile プロファイル名 \
--user-pool-id ap-northeast-1_xxxxxxxxx \
--client-id xxxxxxxxxxxxxxxxxxxxxxxxxx \
--session xxxxxxxxxxxxxxxxxxxxxxxxxx \
--challenge-name NEW_PASSWORD_REQUIRED \
--challenge-responses USERNAME=ユーザー名,NEW_PASSWORD=新パスワード,userAttributes.email=メールアドレス
$ aws cognito-idp admin-respond-to-auth-challenge \
> --profile xxxxxxxxx \
> --user-pool-id ap-northeast-1_xxxxxxxxx \
> --client-id xxxxxxxxxxxxxxxxxxxxxxxxxx \
> --session xxxxxxxxxxxxxxxxxxxxxxxxxx \
> --challenge-name NEW_PASSWORD_REQUIRED \
> --challenge-responses USERNAME=wakuwaku_tarou,NEW_PASSWORD=yY-123456,userAttributes.email=xxx@yyy.com
{
    "ChallengeParameters": {},
    "AuthenticationResult": {
        "AccessToken": "xxxx.xxxx.xxxx",
        "ExpiresIn": 3600,
        "TokenType": "Bearer",
        "RefreshToken": "xxxx.xxxx.xxxx",
        "IdToken": "xxxx.xxxx.xxxx"
    }
}
696-aws-cognito_userpool-cli-2.png

ステータスがCONFIRMEDに変わりました。

[AWS CLI] ユーザー認証

再度 admin-initiate-auth を実行してみます。

$ aws cognito-idp admin-initiate-auth \
> --profile xxxxxxxxx \
> --user-pool-id ap-northeast-1_xxxxxxxxx \
> --client-id xxxxxxxxxxxxxxxxxxxxxxxxxx \
> --auth-flow ADMIN_NO_SRP_AUTH \
> --auth-parameters USERNAME=wakuwaku_tarou,PASSWORD=yY-123456
{
    "ChallengeParameters": {},
    "AuthenticationResult": {
        "AccessToken": "xxxx.xxxx.xxxx",
        "ExpiresIn": 3600,
        "TokenType": "Bearer",
        "RefreshToken": "xxxx.xxxx.xxxx",
        "IdToken": "xxxx.xxxx.xxxx"
    }
}

ステータスが CONFIRMED になったので、今回はトークンを取得できました。

各トークンについては、以下ページで説明されています。
[Amazon Cognito ユーザープール] ユーザープールのトークンの使用

[AWS CLI] ユーザー情報取得

先ほど取得した AccessToken を利用してユーザー情報を取得します。

aws cognito-idp get-user \
--profile プロファイル名 \
--access-token アクセストークン
$ aws cognito-idp get-user \
> --profile xxxxxxxxx \
> --access-token xxxx.xxxx.xxxx
{
    "Username": "wakuwaku_tarou",
    "UserAttributes": [
        {
            "Name": "sub",
            "Value": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
        },
        {
            "Name": "email",
            "Value": "xxx@yyy.com"
        }
    ]
}

IDプールの動作確認

[管理画面] IDプールを作成

696-aws-cognito_idpool-1.png

IDプール名を入力します。

認証プロバイダーは、Cognitoを選択して ユーザープールID アプリクライアントIDを入力します。

プールの作成をクリックします。

696-aws-cognito_idpool-2.png

認証済みID、未認証IDに対して紐づけるIAMロールをそれぞれ選択します。

後述の動作確認のため、認証済みIDに紐づけるIAMロールにはIAMポリシー(AmazonDynamoDBFullAccess)を紐づけておきます。

696-aws-cognito_idpool-3.png

IDプールのIDをメモしておきます。

[AWS CLI] Identity IDを取得

ユーザープールのユーザー認証で取得した IDトークン を利用して Identity ID を取得します。
get-idを利用します。

aws cognito-identity get-id \
--account-id XXXXXXXXXXXX \
--region ap-northeast-1 \
--identity-pool-id ap-northeast-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
--logins cognito-idp.ap-northeast-1.amazonaws.com/ユーザープールID=IDトークン
$ aws cognito-identity get-id \
> --account-id XXXXXXXXXXXX \
> --region ap-northeast-1 \
> --identity-pool-id ap-northeast-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
> --logins cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_xxxxxxxxx=xxxx.xxxx.xxx
{
    "IdentityId": "ap-northeast-1:yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy"
}
696-aws-cognito_idpool-4.png

管理画面からもIDが生成されてることを確認できます。認証プラバイダーごとにIDの合計を確認できます。

[AWS CLI] Credentialsを取得

Identity IDCredentials を取得します。
get-credentials-for-identityを利用します。

aws cognito-identity get-credentials-for-identity \
--region ap-northeast-1 \
--identity-id ap-northeast-1:yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy \
--logins cognito-idp.ap-northeast-1.amazonaws.com/ユーザープールID=IDトークン
$ aws cognito-identity get-credentials-for-identity \
> --region ap-northeast-1 \
> --identity-id ap-northeast-1:yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy \
> --logins cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_xxxxxxxxx=xxxx.xxxx.xxx
{
    "IdentityId": "ap-northeast-1:yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
    "Credentials": {
        "AccessKeyId": "xxxxxxxxxxxxxxxxxxxx",
        "SecretKey": "xxxxxxxxxxxxxxxxxxxx",
        "SessionToken": "xxxxxxxxxxxxxxxxxxxx",
        "Expiration": 1563623576.0
    }
}

[AWS CLI] AWSリソースを操作

取得した Credentials を利用してAWSリソースを操作します。

認証済みIDに紐づけた IAMロール には、DynamoDBのフルアクセス権限をもつ IAMポリシー を紐づけていました。そのため、以下のようにDynamoDBを操作できます。

env AWS_ACCESS_KEY_ID=AccessKeyId \
AWS_SECRET_ACCESS_KEY=SecretKey \
AWS_SECURITY_TOKEN=SessionToken \
aws dynamodb scan \
--region ap-northeast-1 \
--table-name users
$ env AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXX \
> AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXX \
> AWS_SECURITY_TOKEN=XXXXXXXXXXXXXXXXX \
> aws dynamodb scan \
> --region ap-northeast-1 \
> --table-name users
{
    "Items": [
        {
            "message": {
                "S": "cccccccccccccc"
            },
            "user_id": {
                "N": "3"
            },
        ( 省略 )