Okta

オクタ

はじめに

Auth0では、OAuth2.0(RFC6749)で定義されているAuthorization Code Flow、Authorization Code Flow with PKCE(Proof Key for Code Exchange)やImplicit Flow等、各種認証認可フローに対応しています。Auth0やAuth0で提供されるSDKの利用で、各フローを容易に実装できます。
セキュリティ上の理由等でリソース側へのアクセスを停止するために、発行したトークンを無効化する場合、Auth0では、リフレッシュトークンのみ無効化できます。アクセストークンの有効期限を短くすることを前提とし、最新のリフレッシュトークンを無効化することで、新たなアクセストークンの取得を不可とします。その後、アクセストークンの有効期限が切れ、リソースへアクセスできない状態となります。

Auth0でのリフレッシュトークンの無効化方法は、以下の4つです。

  • A)Auth0管理画面上での操作
    対象とするユーザ、Application、Audienceに対する認可に基づき、無効化
  • B)Management API:/api/v2/grants/{id}
    対象とするユーザ、Application、Audienceに対する認可に基づき、無効化
  • C)Authentication API:/oauth/revoke
    対象とするリフレッシュトークンに基づき、無効化
  • D)Management API:/api/v2/device-credentials/{id}
    対象とするユーザ、Applicationのデバイス資格情報に基づき、無効化

本ページでは、Authentication Code Flow(RFC6749 4.1)を例として、Auth0におけるトークン無効化操作を確認します。確認にあたり、必要となるAuth0設定とリフレッシュトークン無効化における具体的な手続きをご紹介します。

前提

本ページ記載の機能及び設定に関する内容は、2023年3月現在の情報となります。

事前設定

Authorization Code Flowにおけるリフレッシュトークン取得にあたり、Auth0側で必要な事前設定は、以下をご確認ください。

また、リフレッシュトークン無効化の確認にあたり、以下の設定をご確認ください。

  • [Settings] > [Advanced]タブで、[Refresh Token Revocation Deletes Grant]が無効化(デフォルト設定)されている
Application設定

補足

無効化方法C)では、無効化範囲が変わります。

  • 無効:無効化対象として指定したリフレッシュトークンのみ無効化
  • 有効:無効化対象として指定したリフレッシュトークンだけでなく、同じユーザ、Application、Audienceの組合せに紐づく他のリフレッシュトークンも同時に無効化

確認手順概要

Authorization Code Flowを例として、Auth0におけるリフレッシュトークンの無効化手続きを確認します。確認手順の概要は、以下の通りです。

  • Auth0 /authorizeエンドポイントへ認可コードをリクエスト
  • Auth0による認証画面表示:ユーザ認証を実施
  • 1.で指定したリダイレクト先へ遷移:URLから認可コードを確認
  • Auth0 /oauth/tokenエンドポイントにアクセスし、アクセストークンとIDトークン、リフレッシュトークンを取得
  • 取得したアクセストークンとIDトークンを確認
  • 4.で取得したリフレッシュトークンを利用してAuth0 /oauth/tokenエンドポイントにアクセスし、IDトークンとアクセストークンを再取得
  • 再取得したアクセストークンとIDトークンを確認
  • 6.で取得したリフレッシュトークンを無効化
  • 無効化したリフレッシュトークンを利用して、アクセストークンを再取得できないことを確認

確認手順

1. Auth0 /authorizeエンドポイントへ認可コードをリクエスト
Webブラウザにて以下URLへアクセス
https://<YOUR_AUTH0_TENANT_NAME>.<REGION_DOMAIN>.auth0.com/authorize?audience=https://example.com&response_type=code&scope=openid profile email offline_access&client_id=8XVChmTIfdfYdqHSrHW3meOxGtds6iiS&redirect_uri=https://example.com

補足

  • <YOUR_AUTH0_TENANT_NAME>:Auth0テナント名
  • <REGION_DOMAIN>:Auth0テナントリージョン名
  • audience=https://example.com:事前設定におけるAPI設定のIdentifier
  • response_type=code&scope=openid:Authorization Code Flow利用+IDトークン取得
  • scope=offline_access:リフレッシュトークン取得
  • client_id:事前設定におけるApplication設定のClient ID
  • redirect_uri:認証完了後のリダイレクト先URL
2. Auth0による認証画面表示:ユーザ認証を実施
Auth0による認証画面表示:ユーザ認証を実施
3. 1.で指定したリダイレクト先へ遷移:URLから認可コードを確認
1.で指定したリダイレクト先へ遷移:URLから認可コードを確認
https://example.com/?code=tpP_z1EYtGiHy4zOb_lysQKfX7n5jkfOjmpJL1NTN1mwA
4. Auth0 /oauth/tokenエンドポイントにアクセスし、アクセストークンとIDトークン、リフレッシュトークンを取得
> curl -X POST --url 'https://<YOUR_AUTH0_TENANT_NAME>.<REGION_DOMAIN>.auth0.com/oauth/token' --header 'content-type: application/x-www-form-urlencoded' --data 'grant_type=authorization_code&client_id=8XVChmTIfdfYdqHSrHW3meOxGtds6iiS&client_secret=sp53lHTcaRUjyogn7veTj0mpE0zt6IAQ8D9fLNaMYZFX3uaoaLAg0-D5EmW8m6_d&code=tpP_z1EYtGiHy4zOb_lysQKfX7n5jkfOjmpJL1NTN1mwA&redirect_uri=https://example.com'

補足

  • grant_type=authorization_code:Authorization Code Flow利用
  • client_id:事前設定におけるApplication設定のClient ID
  • client_secret:事前設定におけるApplication設定のClient Secret
  • code:3.で取得した認可コード
取得結果
{
	"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6Ikp...(略)...qvVPSppORhoOjSQLj170Q",
	"refresh_token":"v1.MUKtIl2YJGb7zr8miZ0W0i6Sp...(略)...gIMhDd6b4OcBQu2qBTuGI",
	"id_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCI...(略)...Bwf8epG61vPgTk5oQ9p7A",
	"scope":"openid profile email offline_access",
	"expires_in":86400,
	"token_type":"Bearer"
}
5. 取得したアクセストークンとIDトークンを確認
jwt.ioにてアクセストークン、IDトークンをデコード
アクセストークンのデコード結果
{
	"iss": "https://..auth0.com/",
	"sub": "auth0|63edd8308f9c50bfb575e326",
	"aud": [
	"https://example.com",
	"https://..auth0.com/userinfo"
	],
	"iat": 1677565426,
	"exp": 1677651826,
	"azp": "8XVChmTIfdfYdqHSrHW3meOxGtds6iiS",
	"scope": "openid profile email offline_access"
}
IDトークンのデコード結果
{
	"nickname": "xxxxxxxx",
	"name": "xxxxxxx@xxxxxxxx.co.jp",
	"picture": "https://s.gravatar.com/avatar/24b5f30a0fe65625e5afb...(略)...%2Fim.png",
	"updated_at": "2023-02-28T06:19:01.349Z",
	"email": "xxxxxxx@xxxxxxxx.co.jp",
	"email_verified": true,
	"iss": "https://..auth0.com/",
	"sub": "auth0|63edd8308f9c50bfb575e326",
	"aud": "8XVChmTIfdfYdqHSrHW3meOxGtds6iiS",
	"iat": 1677565426,
	"exp": 1677601426,
	"sid": "wR4eASabw79mKLy2Rgfk5LzPy8gpuwlY"
}
6. 4.で取得したリフレッシュトークンを利用してAuth0 /oauth/tokenエンドポイントにアクセスし、IDトークンとアクセストークンを再取得
> curl -X POST --url 'https://<YOUR_AUTH0_TENANT_NAME>.<REGION_DOMAIN>.auth0.com/oauth/token' --header 'content-type: application/x-www-form-urlencoded' --data 'grant_type=refresh_token&client_id=8XVChmTIfdfYdqHSrHW3meOxGtds6iiS&client_secret=sp53lHTcaRUjyogn7veTj0mpE0zt6IAQ8D9fLNaMYZFX3uaoaLAg0-D5EmW8m6_d&refresh_token=v1.MUKtIl2YJGb7zr8miZ0W0i6Sp...(略)...gIMhDd6b4OcBQu2qBTuGI&redirect_uri=https://example.com'

補足

  • grant_type=refresh_token:リフレッシュトークンによるトークン再取得
  • client_id:事前設定におけるApplication設定のClient ID
  • client_secret:事前設定におけるApplication設定のClient Secret
  • refresh_token:4.で取得したリフレッシュトークン
取得結果
{
	"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6Ikp...(略)...qrPFWEhjYOiky3uUTwk-lGSg",
	"refresh_token":"v1.MkKtIl2YJGb7zr8miZ0W0i53wu...(略)...q4-HWZ3vdMI6JjaD5rDxNk",
	"id_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCI...(略)...sDIbq9qg9Bzg3kcWk8cEWw",
	"scope":"openid profile email offline_access",
	"expires_in":86400,
	"token_type":"Bearer"
}

補足

  • リフレッシュトークンのローテーション機能を有効化(デフォルト:有効)することで、リフレッシュトークンを用いてアクセストークンを再取得した際、新たなリフレッシュトークンが返却されます。
    Refresh Token Rotation - Auth0 docs
7. 再取得したアクセストークンとIDトークンを確認
jwt.ioにてアクセストークン、IDトークンをデコードし、発行(iatクレーム)と有効期限(expクレーム)が5.の確認結果と異なることを確認
再取得したアクセストークンのデコード結果
{
	"iss": "https://..auth0.com/",
	"sub": "auth0|63edd8308f9c50bfb575e326",
	"aud": [
	"https://example.com",
	"https://..auth0.com/userinfo"
	],
	"iat": 1677565856,
	"exp": 1677652256,
	"azp": "8XVChmTIfdfYdqHSrHW3meOxGtds6iiS",
	"scope": "openid profile email offline_access"
}
再取得したIDトークンのデコード結果
{
	"nickname": "xxxxxxxx",
	"name": "xxxxxxx@xxxxxxxx.co.jp",
	"picture": "https://s.gravatar.com/avatar/24b5f30a0fe65625e5afb...(略)...%2Fim.png",
	"updated_at": "2023-02-28T06:19:01.349Z",
	"email": "xxxxxxx@xxxxxxxx.co.jp",
	"email_verified": true,
	"iss": "https://..auth0.com/",
	"sub": "auth0|63edd8308f9c50bfb575e326",
	"aud": "8XVChmTIfdfYdqHSrHW3meOxGtds6iiS",
	"iat": 1677565856,
	"exp": 1677601856
}
8. 6.で取得したリフレッシュトークンを無効化
A) Auth0管理画面上での操作
  • [User Management] > [Users]をクリック
  • 無効化対象のリフレッシュトークンに紐づくユーザをクリック
  • [Authorized Applications]タブをクリック
  • 無効化対象のリフレッシュトークンに紐づくApplication及びAudienceを確認し、[Revoke]ボタンをクリック
Auth0管理画面上での操作
  • 確認画面で[Yes, Revoke]ボタンをクリック
確認画面で[Yes, Revoke]ボタンをクリック
  • 無効化した対象が一覧から消えたことを確認
B) Management API:/api/v2/grants/{id}
  • ユーザ、Application、Audienceをキーとしてアクティブな認可を検索(GET:/api/v2/grants)
> curl -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5...(略)...T9XmWcw" https://<YOUR_AUTH0_TENANT_NAME>.<REGION_DOMAIN>.auth0.com/api/v2/grants?user_id=auth0%7C63edd8308f9c50bfb575e326\&client_id=8XVChmTIfdfYdqHSrHW3meOxGtds6iiS\&audience=https://example.com

補足

  • user_id:無効化対象ユーザのUser ID
  • client_id:無効化対象ApplicationのClient ID
  • audience:無効化対象Audience(API設定のIdentifier)
実行結果
[
	{
		"user_id":"auth0|63edd8308f9c50bfb575e326",
		"audience":"https://example.com",
		"scope":["openid","profile","email","offline_access"],
		"clientID":"8XVChmTIfdfYdqHSrHW3meOxGtds6iiS",
		"id":"6430dbcc408feb3521dec7b7"
	}
]
> curl -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5..(略)...T9XmWcw" -X DELETE https://<YOUR_AUTH0_TENANT_NAME>.<REGION_DOMAIN>.auth0.com/api/v2/grants/6430dbcc408feb3521dec7b7
C) Authentication API:/oauth/revoke
  • 無効化するリフレッシュトークン値を指定し、リフレッシュトークンを無効化
> curl -X POST --url 'https://<YOUR_AUTH0_TENANT_NAME>.<REGION_DOMAIN>.auth0.com/oauth/revoke' --header 'content-type: application/json' --data '{ "client_id": "8XVChmTIfdfYdqHSrHW3meOxGtds6iiS", "client_secret": "sp53lHTcaRUjyogn7veTj0mpE0zt6IAQ8D9fLNaMYZFX3uaoaLAg0-D5EmW8m6_d", "token": "v1.MkKtIl2YJGb7zr8miZ0W0i53wu...(略)...q4-HWZ3vdMI6JjaD5rDxNk" }

補足

  • client_id:無効化対象ApplicationのClient ID
  • client_secret:無効化対象ApplicationのClient Secret
  • token:無効化するリフレッシュトークン
D) Management API:/api/v2/device-credentials/{id}
> curl -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5...(略)...T9XmWcw" https://<YOUR_AUTH0_TENANT_NAME>.<REGION_DOMAIN>.auth0.com/api/v2/device-credentials?user_id=auth0%7C63edd8308f9c50bfb575e326\&client_id=8XVChmTIfdfYdqHSrHW3meOxGtds6iiS\&type=rotating_refresh_token

補足

  • user_id:無効化対象ユーザのUser ID
  • client_id:無効化対象ApplicationのClient ID
  • type=rotating_refresh_token:ローテーションが有効なリフレッシュトークンを対象
実行結果
[
	{
		"id":"dcr_v7ElzV8tQhFebE4n",
		"device_name":"Chrome",
		"client_id":"8XVChmTIfdfYdqHSrHW3meOxGtds6iiS",
		"user_id":"auth0|63edd8308f9c50bfb575e326",
		"type":"rotating_refresh_token"
	}
]
> curl -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5..(略)...T9XmWcw" -X DELETE https://<YOUR_AUTH0_TENANT_NAME>.<REGION_DOMAIN>.auth0.com/api/v2/device-credentials/dcr_v7ElzV8tQhFebE4n
9. 無効化したリフレッシュトークンを利用して、アクセストークンを再取得できないことを確認
> curl -X POST --url 'https://<YOUR_AUTH0_TENANT_NAME>.<REGION_DOMAIN>.auth0.com/oauth/token' --header 'content-type: application/x-www-form-urlencoded' --data 'grant_type=refresh_token&client_id=8XVChmTIfdfYdqHSrHW3meOxGtds6iiS&client_secret=sp53lHTcaRUjyogn7veTj0mpE0zt6IAQ8D9fLNaMYZFX3uaoaLAg0-D5EmW8m6_d&refresh_token=v1.MkKtIl2YJGb7zr8miZ0W0i53wu...(略)...q4-HWZ3vdMI6JjaD5rDxNk&redirect_uri=https://example.com'

補足

  • refresh_token:8.で無効化したリフレッシュトークン
実行結果

無効なリフレッシュトークンである旨のエラーが返されます。

{
	"error":"invalid_grant",
	"error_description":"Unknown or invalid refresh token."
}

おわりに

Auth0におけるトークン無効化について、Authorization Code Flowを例として、リフレッシュトークン無効化手続きをご紹介しました。Auth0におけるトークン無効化処理の理解に役立てていただければ幸いです。

参考情報

RFC 7009:OAuth 2.0 Token Revocationでは、無効化するトークンの対象として、リフレッシュトークン(必須)とアクセストークン(推奨)が言及されています。

Implementations MUST support the revocation of refresh tokens and SHOULD support the revocation of access tokens (see Implementation Note).
RFC 7009:OAuth 2.0 Token Revocation

参考

お問い合わせ・資料請求

株式会社マクニカ  Okta 担当

月~金 8:45~17:30