[アップデート] Amazon Cognito のリフレッシュトークンでローテーション機能が使えるようになりました
いわさです。
Amazon Cognito ユーザープールでは認証時に ID トークン / アクセストークン / リフレッシュトークンが払い出されます。
一般的には ID トークンとアクセストークンは短い有効期間を設定し、有効期間の長いリフレッシュトークンで新しいアクセストークンを取得したりします。
これまで Cognito ユーザープールでは、このリフレッシュトークンの有効期間内であれば何度でもトークンの更新を行うことが出来ていたのですが、先日のアップデートでリフレッシュトークンのローテーション機能が追加されました。
ローテーションを行うことで、リフレッシュトークン使用後に ID トークンとアクセストークンの取得に加えて、新しいリフレッシュトークンが取得できるようになります。
この時、古いリフレッシュトークンは使えなくなる、という仕組みです。
リフレッシュトークンの有効期間については古いトークンの残り期間が引き継がれるようなので、用途としては自動更新し続けることができるというものではなく、リフレッシュトークン漏洩などのリスクに対処できるようになります。
従来のリフレッシュトークンの使い方
従来からユーザープールのクライアントで、各トークンの有効期限を設定することが出来ました。
リフレッシュトークンは 60分~10年の期間、ID/アクセストークンは5分~1日です。
initiate-auth
でリフレッシュトークンも一緒に取得することができます。
% aws cognito-idp initiate-auth --cli-input-json file://initiate-auth.json
{
"ChallengeParameters": {},
"AuthenticationResult": {
"AccessToken": "eyJ...Hew",
"ExpiresIn": 3600,
"TokenType": "Bearer",
"RefreshToken": "eyJ...hiA",
"IdToken": "eyJ...fwQ"
}
}
アクセストークンの有効期間が切れた時は、再認証しても良いのですが、上記リフレッシュトークンを使うことで再認証を要求せずに新しいアクセストークンを取得することが出きます。
AuthFlow
にREFRESH_TOKEN_AUTH
を指定することでトークン更新を要求します。
% cat initiate-auth-refresh.json
{
"AuthFlow": "REFRESH_TOKEN_AUTH",
"AuthParameters": {
"REFRESH_TOKEN": "eyJ...2iQ"
},
"ClientId": "4oar6ocl42sncct16o98jgibma"
}
% aws cognito-idp initiate-auth --cli-input-json file://initiate-auth-refresh.json
{
"ChallengeParameters": {},
"AuthenticationResult": {
"AccessToken": "eyJ...UJQ",
"ExpiresIn": 3600,
"TokenType": "Bearer",
"IdToken": "eyJr...LsA"
}
}
新しいアクセストークンと ID トークンを取得することが出来ました。
リフレッシュトークンのローテーションを有効にしてみる
今回のアップデートで次の「更新トークンのローテーションを有効にする」というオプションが追加されています。
デフォルトは OFF で、かつ「既存の認証済みセッションから新しいユーザートークンを取得します」が有効な場合は使うことが出来ません。
上記にて有効化して先ほどと同じようにトークン更新を試してみましょう。
% aws cognito-idp initiate-auth --cli-input-json file://initiate-auth-refresh.json
An error occurred (UnsupportedOperationException) when calling the InitiateAuth operation: This API does not support refresh token rotation
initiate-auth
でトークン更新ができなくなりました。
ドキュメントにも記載されているのですが、ローテーションを有効化した場合は従来の方法でのトークン更新ができなくなります。
アップデートにあわせて新しいトークン更新 API get-tokens-from-refresh-token
が追加されていますので、こちらを使います。
% cat get-tokens-from-refresh-token.json
{
"RefreshToken": "eyJ...TYQ",
"ClientId": "4oar6ocl42sncct16o98jgibma"
}
% aws cognito-idp get-tokens-from-refresh-token --cli-input-json file://get-tokens-from-refresh-token.json
{
"AuthenticationResult": {
"AccessToken": "eyJ...F6Q",
"ExpiresIn": 300,
"TokenType": "Bearer",
"RefreshToken": "eyJ...kow",
"IdToken": "eyJ...0A"
}
}
新しいアクセストークン、IDトークンに加えて新しいリフレッシュトークンも取得されるようになりました。
ここで、古いリフレッシュトークンを使ってみるとどうなるでしょうか。
% aws cognito-idp get-tokens-from-refresh-token --cli-input-json file://get-tokens-from-refresh-token.json
An error occurred (RefreshTokenReuseException) when calling the GetTokensFromRefreshToken operation: Refresh token reuse detected
拒否されましたね。古いリフレッシュトークンが使えなくなりました。
で、新しいリフレッシュトークンも試してみます。
% aws cognito-idp get-tokens-from-refresh-token --cli-input-json file://get-tokens-from-refresh-token.json
{
"AuthenticationResult": {
"AccessToken": "eyJ...tTg",
"ExpiresIn": 300,
"TokenType": "Bearer",
"RefreshToken": "eyJ...-mw",
"IdToken": "eyJ...tvw"
}
}
こちらは成功しましたね。
古いリフレッシュトークンが使えなくなるのはデフォルトでは0秒(即時)なのですが、最大60秒まで旧トークンを有効化しておくことが出来ます。再試行処理などを行いたいときなどに利用することが出来ます。
さいごに
本日は Amazon Cognito のリフレッシュトークンでローテーション機能が使えるようになったので使ってみました。
セキュリティ対策としてリフレッシュトークンのローテーションをしたい場合に利用出来ます。
従来のinitiate-auth
でそのままこの機能が使えれば一番良かったのですが、新しい API を使う必要があるという点に注意が必要ですね。
アプリケーション側の改修が必要となります。
また、アクセストークンと ID トークンに JWT クレームが少し追加されるので JWT のサイズが大きくなる点も注意しましょう。