Amplifyを使うと、AWSと連携したWebアプリをとても簡単に作成できます。 AWSのバックエンドをほとんど意識せず、フロントエンドのコーディングに集中できるのがとても嬉しいです。
Amplifyの提供するライブラリーの中にPubSubがありますので、認証機能と合わせて試してみました。
Amplifyを使うと、AWSと連携したWebアプリをとても簡単に作成できます。 AWSのバックエンドをほとんど意識せず、フロントエンドのコーディングに集中できるのがとても嬉しいです。
Amplifyの提供するライブラリーの中にPubSubがありますので、認証機能と合わせて試してみました。
過去にQiitaに投稿した内容のアーカイブです。
ブラウザからのユーザーアクセスであればamazon-cognito-identity-jsを使ってユーザーの追加、ログインは簡単にできますが、どうにかサーバーサイドでできないものか、調査しました。 Javaのプログラムからユーザー追加やログイン(トークンの取得)ができましたので紹介します。
ユーザープールを作成します。ユーザーの登録以降のフローは異なりますが、ユーザープールを作成する手順まではこちらのサイトが参考になると思います。
AWS SDKを使う設定をします。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'
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);
勉強中です。