LoginSignup
30

More than 5 years have passed since last update.

Java用SDKからCognito User Poolsを使用する

Last updated at Posted at 2017-05-01

ブラウザからのユーザーアクセスであればamazon-cognito-identity-jsを使ってユーザーの追加、ログインは簡単にできますが、どうにかサーバーサイドでできないものか、調査しました。
Javaのプログラムからユーザー追加やログイン(トークンの取得)ができましたので紹介します。

前準備(マネジメントコンソール)

ユーザープールを作成します。ユーザーの登録以降のフローは異なりますが、ユーザープールを作成する手順まではこちらのサイトが参考になると思います。

前準備(Java)

AWS SDKを使う設定をします。Gradleの場合は、build.gradleに以下の内容を追加します。

build.gradle
    // https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-cognitoidp
    compile group: 'com.amazonaws', name: 'aws-java-sdk-cognitoidp', version: '1.11.123'

AWSCognitoIdentityProviderの作成

AWSCredentialsProviderとリージョン(今回は東京リージョン)を引数に渡して、AWSCognitoIdentityProviderを作成します。

AWSCredentialsProviderの作成方法は色々あるようですが、今回はこちらを参考にProfileCredentialsProviderを使用しました。

AWSCredentialsProvider credentialsProvider = new ProfileCredentialsProvider("プロファイル名");

AWSCognitoIdentityProvider client = AWSCognitoIdentityProviderClientBuilder.standard()
                                        .withCredentials(credentialsProvider)
                                        .withRegion(Regions.AP_NORTHEAST_1)
                                        .build();

ユーザーの新規作成

ユーザーを新規作成します。
ユーザープールIDはマネジメントコンソールで確認できます。

AdminCreateUserRequest adminCreateUserRequest = new AdminCreateUserRequest();
adminCreateUserRequest
    .withUserPoolId("ユーザープールID")
    .withUsername("新規作成するユーザーのユーザー名")
    .withTemporaryPassword("新規作成するユーザーの一時パスワード");
AdminCreateUserResult response = client.adminCreateUser(adminCreateUserRequest);

トークンの取得

ユーザーIDとパスワードを使ってトークンを取得します。クライアントIDはマネジメントコンソール上の「Apps」のところにあります。
※Appsの設定のEnable sign-in API for server-based authentication (ADMIN_NO_SRP_AUTH)は有効になっている必要があります。

Map<String, String> authParameters = new HashMap<>();
authParameters.put("USERNAME", "ユーザー名");
authParameters.put("PASSWORD", "パスワード");

AdminInitiateAuthRequest request = new AdminInitiateAuthRequest();
request
    .withAuthFlow(AuthFlowType.ADMIN_NO_SRP_AUTH)
    .withUserPoolId("ユーザープールID")
    .withClientId("クライアントID")
    .withAuthParameters(authParameters);

AdminInitiateAuthResult response = client.adminInitiateAuth(request);

成功するとトークンが取得できます。(加工しています)

System.out.println(response.getAuthenticationResult().toString());
トークン取得成功時
{
  AccessToken: xxxxx,
  ExpiresIn: 3600,
  TokenType: Bearer,
  RefreshToken: yyyyy,
  IdToken: zzzzz,
}

ただし、新規作成したばかりのユーザーは、パスワード変更の必要があるため、トークンは取得できません。その場合、ChallengeNameが「NEW_PASSWORD_REQUIRED」となってしまいますので、次の一時パスワード変更を行います。
(トークン取得成功時はChallengeNameがnull、トークン取得失敗時はAuthenticationResultがnullになるようです)

System.out.println(response.getChallengeName());
トークン取得失敗時
NEW_PASSWORD_REQUIRED

一時パスワード変更

一時パスワード変更処理です。adminInitiateAuthのレスポンスで受け取るChallengeNameとSessionが必要になります。

Map<String, String> challengeResponses = new HashMap<>();
challengeResponses.put("USERNAME", "ユーザー名");
challengeResponses.put("NEW_PASSWORD", "変更後の新しいパスワード");

AdminRespondToAuthChallengeRequest request = new AdminRespondToAuthChallengeRequest();
request  
    .withChallengeName(adminInitiateAuthResult.getChallengeName())
    .withUserPoolId("ユーザープールID")
    .withClientId("クライアントID")
    .withSession(adminInitiateAuthResult.getSession())
    .withChallengeResponses(challengeResponses);

AdminRespondToAuthChallengeResult response = client.adminRespondToAuthChallenge(request);

上手く行けば、この手順を持ってトークンが取得できます。

System.out.println(response.getAuthenticationResult().toString());
{
  AccessToken: xxxxx,
  ExpiresIn: 3600,
  TokenType: Bearer,
  RefreshToken: yyyyy,
  IdToken: zzzzz,
}

トークンの更新

リフレッシュトークンを使用してのトークンの更新は、トークンの取得と同様adminInitiateAuthメソッドにて行います。
authParametersの値とAuthFlowが違うだけです

Map<String, String> authParameters = new HashMap<>();
authParameters.put("REFRESH_TOKEN", "リフレッシュトークン");

AdminInitiateAuthRequest request = new AdminInitiateAuthRequest();
request
    .withAuthFlow(AuthFlowType.REFRESH_TOKEN_AUTH)
    .withUserPoolId("ユーザープールID")
    .withClientId("クライアントID")
    .withAuthParameters(authParameters);

AdminInitiateAuthResult response = client.adminInitiateAuth(request);

取得したトークンの利用方法など

勉強中です。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30