はじめに
- App IDとLibertyをOpenID Connect Clientで連携して、認証部分をそれっぽく実装したことはあったのですが、Cognitoでも同じことできるんだっけ??と思ったので試してみたという話です。
- 基本はApp IDのドキュメントに記述されているLiberty for Java SDK の構成と同じ手順で問題ありませんでしたが、当然ながらApp IDとCognitoでURLの指定など異なる部分もありますので、本記事ではLibertyとCognitoを連携するにあたって必要な部分のみを記述します。
注意
- この例では、ユーザープールをus-east-2に作っています。us-east-2と記述されている部分については、ご自身の環境に合わせて適宜読み替えてください。
- この例では、ローカル環境のLibertyからCognitoへの接続を例として記載しています。ドメインなどは、ご自身の環境に合わせて適宜読み替えてください。
server.xmlの構成
① CognitoのユーザープールIDを取得します。
$ aws cognito-idp list-user-pools --max-results 10
{
"UserPools": [
{
"Id": "us-east-2_xxxxxxxxx",
"Name": "cognito-test",
"LambdaConfig": {},
"LastModifiedDate": "2022-06-02T17:16:58.221000+09:00",
"CreationDate": "2022-06-02T14:11:36.733000+09:00"
}
]
}
② ユーザープールIDをキーとして、client_idを取得します。
$ aws cognito-idp list-user-pool-clients --user-pool-id us-east-2_xxxxxxxxx
{
"UserPoolClients": [
{
"ClientId": "xxxxxxxxxxxxxxxxxxxxxxxxxx",
"UserPoolId": "us-east-2_xxxxxxxxx",
"ClientName": "test-client"
}
]
}
③ ユーザープールIDとclient_idをキーとして、client_secretを取得します。
$ aws cognito-idp describe-user-pool-client --user-pool-id us-east-2_xxxxxxxxx --client-id xxxxxxxxxxxxxxxxxxxxxxxxxx
{
"UserPoolClient": {
"UserPoolId": "us-east-2_xxxxxxxxx",
"ClientName": "test-client",
"ClientId": "xxxxxxxxxxxxxxxxxxxxxxxxxx",
"ClientSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"LastModifiedDate": "2022-06-02T17:02:13.501000+09:00",
"CreationDate": "2022-06-02T14:11:37.301000+09:00",
"RefreshTokenValidity": 30,
... (略) ...
"AllowedOAuthFlowsUserPoolClient": true,
"PreventUserExistenceErrors": "ENABLED"
}
}
④ ユーザープールIDをキーとして、Cognitoドメインを取得します。
$ aws cognito-idp describe-user-pool --user-pool-id us-east-2_xxxxxxxxx
{
"UserPool": {
"Id": "us-east-2_xxxxxxxxx",
"Name": "cognito-test",
... (略) ...
"Domain": "xxxxxxxxxx",
"AdminCreateUserConfig": {
"AllowAdminCreateUserOnly": true,
"UnusedAccountValidityDays": 7
},
"UsernameConfiguration": {
"CaseSensitive": false
},
"Arn": "arn:aws:cognito-idp:us-east-2:xxxxxxxxxxxx:userpool/us-east-2_xxxxxxxxx",
"AccountRecoverySetting": {
"RecoveryMechanisms": [
{
"Priority": 1,
"Name": "verified_email"
}
]
}
}
}
⑤ server.xmlにOpenID Connect Client Featureを作成し、下記の通り定義します。
※ httpsRequired="false"の記述は、ローカル環境などhttpで接続する環境の場合にのみ必要です。
<openidConnectClient id="{任意のid}"
clientId="{②で取得したClientId}"
clientSecret="{③で取得したClientSecret}"
authorizationEndpointUrl="https://{④で取得したDomain}.auth.us-east-2.amazoncognito.com/oauth2/authorize"
tokenEndpointUrl="https://{④で取得したDomain}.auth.us-east-2.amazoncognito.com/oauth2/token"
jwkEndpointUrl="https://cognito-idp.us-east-2.amazonaws.com/{①で取得したId}/.well-known/jwks.json"
issuerIdentifier="https://cognito-idp.us-east-2.amazonaws.com/{①で取得したId}"
tokenEndpointAuthMethod="basic"
signatureAlgorithm="RS256"
scope="openid"
httpsRequired="false"
redirectToRPHostAndPort="http://localhost:9080"
/>
コールバックURLの設定
Cognitoからの戻り先を設定します。
$ aws cognito-idp update-user-pool-client --user-pool-id us-east-2_xxxxxxxxx --client-id xxxxxxxxxxxxxxxxxxxxxxxxxx --callback-urls "http://localhost:9080/oidcclient/redirect/{⑤で指定したid}"
{
"UserPoolClient": {
"UserPoolId": "us-east-2_xxxxxxxxx",
"ClientName": "test-client",
"ClientId": "xxxxxxxxxxxxxxxxxxxxxxxxxx",
"ClientSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"LastModifiedDate": "2022-06-03T12:25:21.303000+09:00",
"CreationDate": "2022-06-02T14:11:37.301000+09:00",
"RefreshTokenValidity": 30,
"CallbackURLs": [
"http://localhost:9080/oidcclient/redirect/{⑤で指定したid}"
],
"AllowedOAuthFlowsUserPoolClient": false,
"PreventUserExistenceErrors": "ENABLED"
}
}
ここが適切に設定されていない場合、次のようなエラー(redirect_mismatch)になります。
Keystoreの構成
Keystoreに適切な署名者証明書が追加されていない場合、ログに下記のようなエラーが出力される場合があります。
[ERROR ] CWPKI0823E: SSL ハンドシェークの失敗: SubjectDN [CN=*.auth.us-east-2.amazoncognito.com] の署名者がホスト [xxxxxxxxxx.auth.us-east-2.amazoncognito.com:443] から送信されました。 SSL 構成別名 [defaultSSLConfig] にあるトラストストア [...(略).../resources/security/key.p12] にこの署名者を追加する必要がある可能性があります。 SSL ハンドシェーク例外からの拡張エラー・メッセージ: [unable to find valid certification path to requested target]
[ERROR ] CWWKS1708E: OpenID Connect クライアント [xxxxxxxxxxxxxxxxxxxxxxxxxx] は、[https://xxxxxxxxxx.auth.us-east-2.amazoncognito.com/oauth2/token] に OpenID Connect プロバイダーに接続して ID トークンを受け取ることができません。原因は [unable to find valid certification path to requested target] です。
このエラーが出力された場合は、接続先のCognitoホスト(*.auth.us-east-2.amazoncognito.com と cognito-idp.us-east-2.amazonaws.com)の証明書を取得し、Libertyのセキュリティ設定を適切に構成する必要があります。
Libertyに証明書を追加する方法は下記に記載されていますので、本記事では割愛します。