Cognito+SpringBoot+SpringSecurityでOAuth2認証する時の設定
散々嵌りまくったので設定方法や踏んだ地雷についてのメモ
ユーザープールを作る
単純なOAuth2認証がしたいだけの場合はユーザープールを作成。
「属性」の設定
ユーザー名かEmail/電話番号か
- 任意のユーザー名を付けたい場合はユーザー名側を選ぶ必要あり
- Email/電話番号を選ぶと、内部的なユーザー名はランダムな文字列になる
カスタム属性
カスタム属性はPrincipalから取れる
//custom属性roleがADMINか確かめたい場合
@RequestMapping("/")
public String index(Principal principal) {
if(principal instanceof OAuth2AuthenticationToken) {
OAuth2AuthenticationToken token = (OAuth2AuthenticationToken)principal;
return token.getPrincipal().getAttributes().entrySet().stream().anyMatch(e -> {
return e.getKey().equals("custom:role") && e.getValue().equals("ADMIN");
});
}
///省略
}
なお、カスタム属性はCognitoの設定画面からは設定できないので、
AdminUpdateUserAttributesRequestなどを使って登録する必要がある
ポリシー
一般的な設定でかつ嵌りどころもないので省略。
唯一気を付けるべきは仮パスワードであってもここの制限に引っかかることか。
MFA
多要素認証の設定は一度設定すると取り返しがつかなくなるものもあるので注意。
例えば、MFA用のSMSロールを紐づけると解除できなくなる。(ロールも多要素認証も)
SMSを利用する場合はSMSの利用上限に注意する
こちらの記事でも紹介されているが
SMSの上限がデフォルトだと極めて低。15通程度で上限に達するので事前に上限解放申請をしておくべき。
(ユーザーサポートへの問合せが必要なので即時反映を期待してはいけない)
ワンタイムパスワード利用認証は独自認証画面を作っている時のみ
Google 認証システムに読み込ませるQRコードを生成するライブラリは用意されているものの、
デフォルトのログイン画面では表示してくれない。
アプリクライアント
プール作成時は名前を決めるだけ。
プール作成後に戻ってきて設定を行う必要アリ。
トリガー
最小構成では不要。
独自の認証を差し込みたい場合に。
プールの作成
ここでプールIDが付与される。
プールIDは作成完了画面の他、サイドメニューの全般設定をクリックすると表示される。
(若干分かりにくい)
アプリクライアント(再び)
戻っているとクライアントIDとクライアントシークレットが生成されているので控えておく
普通にOAuth2でつなぐだけならチェックボックスは無視してOK
アプリクライアントの設定
- 有効なIDプロバイダ:Cognito User Pool
- コールバックURL:springの設定におけるredirect-uriの部分。
https://{自サービスのドメイン}/login/oauth2/code/cognito
https限定だが、localhostの場合のみhttpでも可能。 - サインアウトURL:任意のサインアウトURL
- フロー/スコープ Authorization code grant/openid
ドメイン名の選択
使える文字列なら何でもOK
反映に少々時間(10~20分程度)かかる(なぜか削除画面側にのみ反映に時間がかかるという警告が出る)
spring側の設定
application.ymlの設定
spring:
security:
oauth2:
client:
registration:
{アプリクライアント名}:
client-id: {クライアントID}
client-secret: {クライアントシークレット}
client-name: {任意の文字列}
provider: cognito
scope: openid
redirect-uri: {コールバックURI}
authorization-grant-type: authorization_code
provider:
cognito:
authorization-uri: https://{ドメイン名}.auth.ap-northeast-1.amazoncognito.com/oauth2/authorize
token-uri: https://{ドメイン名}.auth.ap-northeast-1.amazoncognito.com/oauth2/token
user-info-uri: https://{ドメイン名}.auth.ap-northeast-1.amazoncognito.com/oauth2/userInfo
user-name-attribute: cognito:username
jwk-set-uri: https://cognito-idp.ap-northeast-1.amazonaws.com/{プールID}/.well-known/jwks.json
WebSecurityConfig
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
//とりあえず全部ログイン要求
@Override
public void configure(HttpSecurity http) throws Exception {
http.oauth2Login().and().authorizeRequests().antMatchers("/**").authenticated().and().csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
リバプロを通す場合の注意点
ユーザー作成時の注意点
招待をメールで送る場合にはSESの設定が必要
デフォルトではSESがSandboxモードになっており、
SESで認証したメールアドレスにしか招待メールを送ることができない。
こちらもSMSの設定と同じくサポートセンターに連絡しないと変更できない設定なので早めに対応しておく必要がある。