1. クライアントのスコープ
クライアント スコープは管理メカニズムですプロトコル マッパーと役割グループ複数のクライアント間で共有できます。個々のクライアントにマッパーを追加する代わりに、クライアント スコープを作成し、それを必要なクライアントに割り当てます。
1.1 デフォルトのスコープとオプションのスコープ
| タイプ | 説明する | クレームはいつトークンに追加されますか? |
|---|---|---|
| デフォルトのクライアントスコープ | すべてのトークンリクエストに自動的に適用されます | 常に — 明示的なリクエストは必要ありません |
| オプションのクライアントスコープ | クライアントリクエストが明示的である場合にのみ適用されます範囲。範囲パラメータ。パラメータ | クライアントが送信した場合のみスコープ=スコープ名 |
例えば:
# Default scopes — luôn có trong token # profile, email, roles, web-origins, acr → tự động áp dụngOptional scopes — chỉ khi request
address, phone, offline_access, microprofile-jwt
Authorization request với optional scope
GET /auth?response_type=code& client_id=my-app& scope=openid profile email phone address offline_access& redirect_uri=...
1.2 組み込みクライアントスコープ
Keycloakは、OIDC標準に従って利用可能なクライアント・スコープを提供します。
| 範囲 | タイプ | クレームの追加 |
|---|---|---|
オープンID | デフォルト | sub、iss、aud、exp、iat、auth_time、nonce、acr、session_state |
プロフィール。プロフィール | デフォルト | 名前、家族名、与えられた名前、優先ユーザー名、性別、生年月日、ロケール、更新日時 |
電子メール | デフォルト | メール、メール認証済み |
役割。役割 | デフォルト | realm_access.roles、resource_access.{client}.roles |
ウェブオリジン | デフォルト | 許可されたオリジン (CORS) |
acr | デフォルト | acr (認証コンテキスト クラス リファレンス) |
住所 | オプション | 住所 (形式、番地、地域、地域、郵便番号、国) |
電話。電話 | オプション | 電話番号、電話番号_認証済み |
オフラインアクセス | オプション | オフライン更新トークンの取得を許可します |
マイクロプロファイル-jwt | オプション | upn、グループ (MicroProfile JWT 仕様) |
1.3 新しいクライアント スコープの作成
入力クライアントスコープ → クライアントスコープの作成
情報を入力してください:
- 名前:
私のカスタムスコープ - 説明: 範囲の説明
- タイプ: デフォルト / オプション / なし
- 同意画面への表示:ユーザーに表示したい場合はON
- 同意画面のテキスト:同意画面に表示される文字列
- トークンスコープに含める: スコープ名を表示する場合に ON
範囲。範囲トークンの請求 - GUIの注文:同意画面の表示順
- 名前:
もっとプロトコル マッパー範囲内に
もっと範囲(ロール スコープ マッピング) ロールを制限する必要がある場合
# Ví dụ: Tạo scope "billing" chứa billing-related claims
Name: billing
Type: Optional
Display on consent screen: ON
Consent screen text: "Access your billing information"
Include in token scope: ON
# Thêm Protocol Mappers:
# 1. User Attribute Mapper: billing_plan → billing_plan claim
# 2. User Attribute Mapper: billing_email → billing_email claim
# 3. Hardcoded Claim: billing_api_version → "v2"
1.4 クライアントへのクライアントスコープの割り当て
クライアント→タブを開くクライアントスコープ
クリッククライアントスコープの追加
スコープを選択して割り当てるデフォルトまたはオプション
# Gán scope bằng Admin CLI
# Lấy client UUID
CLIENT_UUID=$(bin/kcadm.sh get clients -r my-company \
-q clientId=my-app --fields id --format csv --noquotes)
# Lấy client scope UUID
SCOPE_UUID=$(bin/kcadm.sh get client-scopes -r my-company \
-q name=billing --fields id --format csv --noquotes)
# Gán default scope
bin/kcadm.sh update clients/$CLIENT_UUID/default-client-scopes/$SCOPE_UUID \
-r my-company
# Gán optional scope
bin/kcadm.sh update clients/$CLIENT_UUID/optional-client-scopes/$SCOPE_UUID \
-r my-company
1.5 レルムのデフォルトクライアントスコープ
レルムのデフォルトクライアントスコープは自動的に割り当てられますすべての新しいクライアント作成時:
入力クライアントスコープ→一覧を見る
スコープは行います割り当てられたタイプ= レルム レベルのデフォルトまたはオプションは、新しいクライアントに自動的に割り当てられます
管理者 CLI による設定:
# Thêm scope vào realm default scopes bin/kcadm.sh update realms/my-company/default-default-client-scopes/$SCOPE_UUIDThêm scope vào realm optional scopes
bin/kcadm.sh update realms/my-company/default-optional-client-scopes/$SCOPE_UUID
1.6 同意設定
クライアントが持っているとき同意が必要です= ON の場合、クライアントがトークンを受け取る前に、ユーザーは各スコープに同意する必要があります。
各クライアント スコープは構成可能です同意画面への表示そして同意画面のテキスト
ユーザーは以内に同意を取り消すことができますアカウントコンソール→ アプリケーション
同意エントリはユーザーごと、クライアントごとに保存されます
# Consent screen hiển thị:
# ┌────────────────────────────────────────────┐
# │ My Application muốn: │
# │ │
# │ ☑ Access your profile information │ ← scope: profile
# │ ☑ Access your email address │ ← scope: email
# │ ☐ Access your billing information │ ← scope: billing (optional)
# │ ☐ Access your phone number │ ← scope: phone (optional)
# │ │
# │ [Accept] [Cancel] │
# └────────────────────────────────────────────┘
1.7 スコープの評価(スコープ評価)
管理コンソールには、スコープに基づいてトークンの内容をプレビューするツールが用意されています。
クライアント→タブを開くクライアントスコープ → 評価する
入力:ユーザー(ユーザーテストを選択)、スコープパラメータ(オプションのスコープ)
クリック評価する見る:
- 効果的なプロトコル マッパー: マッパーが適用されます
- 効果的な役割範囲のマッピング: トークンに含まれる役割
- 生成されたアクセストークン: アクセストークンのJSONをプレビュー
- 生成されたIDトークン: IDトークンのJSONをプレビュー
- 生成されるユーザー情報: userinfo 応答の JSON をプレビュー
これは非常に便利なツールですデバッグトークンの内容実際にトークンを要求せずに。
2. トークン管理
2.1 アクセストークン
アクセス トークンは、認証情報 (識別情報) を含む JWT です。どのユーザー?アクセス権があるどのリソースですか?.
アクセストークンの構造:
{
"exp": 1711800300, // Expiration time
"iat": 1711800000, // Issued at
"auth_time": 1711799900, // Authentication time
"jti": "token-id", // JWT ID (unique)
"iss": "http://localhost:8080/realms/my-company", // Issuer
"aud": ["my-app", "account"], // Audience
"sub": "user-uuid", // Subject (user ID)
"typ": "Bearer", // Token type
"azp": "my-app", // Authorized party (client ID)
"session_state": "session-id",
"acr": "1", // Authentication Context Class Reference
"scope": "openid profile email",
"sid": "session-id", // Session ID
"email_verified": true,
"name": "John Doe",
"preferred_username": "john",
"given_name": "John",
"family_name": "Doe",
"email": "[email protected]",
"realm_access": {
"roles": ["default-roles-my-company", "admin"]
},
"resource_access": {
"my-app": {
"roles": ["app-admin"]
},
"account": {
"roles": ["manage-account"]
}
}
}
2.2 トークンID
ID トークンには ID 情報が含まれています - ユーザーを確認します誰ですか。クライアント (証明書利用者) に対してのみ、リソース サーバーには送信されません。
{
"exp": 1711800300,
"iat": 1711800000,
"auth_time": 1711799900,
"jti": "id-token-id",
"iss": "http://localhost:8080/realms/my-company",
"aud": "my-app", // Audience = client ID
"sub": "user-uuid",
"typ": "ID",
"azp": "my-app",
"nonce": "nonce-value", // Phải match với authorization request
"session_state": "session-id",
"at_hash": "access-token-hash", // Hash of access token
"acr": "1",
"sid": "session-id",
"email_verified": true,
"name": "John Doe",
"preferred_username": "john",
"email": "[email protected]"
}
2.3 リフレッシュトークン
リフレッシュ トークンは、ユーザーが再度ログインすることなく新しいアクセス トークンを取得するために使用されます。リフレッシュ トークンの有効期間はアクセス トークンよりも長くなります。
# Refresh access token
POST /realms/my-company/protocol/openid-connect/token
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&
refresh_token=REFRESH_TOKEN&
client_id=my-app&
client_secret=CLIENT_SECRET
# Response — access token mới
{
"access_token": "new-access-token",
"expires_in": 300,
"refresh_expires_in": 1800,
"refresh_token": "new-refresh-token", // Refresh token mới (rotation)
"token_type": "Bearer"
}
2.4 セッションとトークンのタイムアウト
内部構成レルム設定 → トークンタブとセッションタブ:
寿命トークン:
| 設定 | 説明する | 推奨値 |
|---|---|---|
| アクセストークンの有効期間 | アクセストークンの有効期間 | 5分(本番) |
| クライアントのログインタイムアウト | ログインフローが完了するまでの最大時間 | 5分 |
| ログインタイムアウト | ログインページの最大滞在時間 | 30分 |
| ログインアクションのタイムアウト | 必要なアクションを行う時間 (電子メールの確認など) | 5分 |
| ユーザー開始アクションの有効期間 | ユーザーが開始したアクションの時間 | 5分 |
| デフォルトの管理者開始アクションの有効期間 | 管理者が開始するアクションの時間 (パスワードのリセット リンク) | 12時 |
セッションの存続期間:
| 設定 | 説明する | 推奨値 |
|---|---|---|
| SSO セッションのアイドル状態 | 一定期間非アクティブな状態が続くとセッションが期限切れになる | 30分 |
| SSO セッション最大値 | セッションは完全に期限切れになります(アクティビティに関係なく) | 10時 |
| SSO セッション アイドル状態 リメンバーミー | 「Remember Me」がオンの場合のセッションアイドル状態 | 30日 |
| SSO セッション Max Remember Me | 「Remember Me」ON時のセッション最大値 | 30日 |
| クライアントセッションアイドル状態 | クライアントセッションのアイドル状態 (トークンのリフレッシュに影響) | SSO セッションアイドル状態を継承 |
| クライアントセッション最大値 | クライアント セッションの最大値 (トークンの更新に影響します) | SSO セッション最大値を継承 |
セッションとトークンの関係:
# Refresh token expiration = MIN(Client Session Idle, Client Session Max) # Nếu Client Session = 0 → dùng SSO Session valuesVí dụ:
SSO Session Idle = 30 phút
SSO Session Max = 10 giờ
Access Token Lifespan = 5 phút
Client Session Idle = 0 (kế thừa SSO)
Client Session Max = 0 (kế thừa SSO)
→ Access token sống 5 phút
→ Refresh token sống tối đa 30 phút (idle) hoặc 10 giờ (max)
→ Nếu user hoạt động liên tục, session kéo dài đến SSO Session Max
クライアントレベルでオーバーライドします。
各クライアントはタブのレルムレベルのトークン設定をオーバーライドできます。高度な:
Client → Advanced → Advanced Settings:
Access Token Lifespan: 60 # Override: 1 phút cho high-security API
Client Session Idle: 900 # Override: 15 phút idle
Client Session Max: 3600 # Override: 1 giờ max
2.5 リフレッシュトークンの取り消し(ローテーション)
オンにした場合リフレッシュトークンの取り消し、リフレッシュ トークンを使用して新しいアクセス トークンを取得するたびに、古いリフレッシュ トークンが取り消され、新しいリフレッシュ トークンが発行されます。
# Realm Settings → Tokens tab
Revoke Refresh Token: ON
Refresh Token Max Reuse: 0 # Refresh token chỉ dùng 1 lần
# > 0: cho phép reuse N lần (cho network retry)
リフレッシュ トークンのローテーションが必要なのはなぜですか?
リフレッシュ トークンが盗まれた場合、攻撃者はそれを 1 回しか使用できません
正規のクライアントが同じリフレッシュトークンを使用 → 両方とも無効化 → トークンの盗難が検出
これはベストプラクティスが推奨されますOAuth 2.0 セキュリティ BCP で
3. オフラインアクセス
オフライントークンによりクライアントは許可されますユーザーがオンラインでないときでもリソースにアクセスできます(ブラウザセッションなし)。オフライン トークンの有効期間は非常に長く、サーバーを再起動しても存続します。
3.1 オフラインアクセスの構成
範囲を確保する
オフラインアクセスクライアントに割り当てられます (スコープはオプション)クライアントはトークンを要求します
スコープ=オフラインアクセス[レルム設定] → [セッション] タブでオフライン セッション タイムアウトを構成します。
| 設定 | 説明する | 推奨値 |
|---|---|---|
| オフラインセッションアイドル状態 | オフラインセッションはアイドル後に期限切れになります | 30日 |
| オフラインセッションの最大制限 | 最大ライフタイム制限をオンにする | の上 |
| オフラインセッション最大値 | オフラインセッションの最大有効期間 | 60日 |
# Request offline token
GET /auth?response_type=code&
client_id=my-app&
scope=openid offline_access&
redirect_uri=...
# Token response — refresh_token là offline token
{
"access_token": "...",
"expires_in": 300,
"refresh_expires_in": 0, // 0 = offline token (không expire theo session)
"refresh_token": "offline-token",
"token_type": "Bearer",
"scope": "openid offline_access"
}
# Sử dụng offline token để refresh
POST /token
grant_type=refresh_token&
refresh_token=offline-token&
client_id=my-app&
client_secret=CLIENT_SECRET
3.2 オフラインセッションの管理
管理コンソール →セッション→タブオフラインセッション: すべてのオフライン セッションを表示
ユーザーアカウントコンソール→セッション: ユーザーはオフライン セッションを表示および取り消すことができます
管理 REST API: オフライン セッションをプログラムで取り消す
# Revoke offline session cho user cụ thể
DELETE /admin/realms/my-company/users/{user-id}/consents/{client-id}
# Revoke tất cả sessions (bao gồm offline) cho user
POST /admin/realms/my-company/users/{user-id}/logout
4. トークンの取り消し
4.1 トークン失効エンドポイント (RFC 7009)
Keycloakは、クライアントがアクセス・トークンまたはリフレッシュ・トークンを取り消すことを可能にするトークン取り消しエンドポイントをサポートしています。
# Revoke refresh token
POST /realms/my-company/protocol/openid-connect/revoke
Content-Type: application/x-www-form-urlencoded
token=REFRESH_TOKEN&
token_type_hint=refresh_token&
client_id=my-app&
client_secret=CLIENT_SECRET
# Revoke access token
POST /realms/my-company/protocol/openid-connect/revoke
Content-Type: application/x-www-form-urlencoded
token=ACCESS_TOKEN&
token_type_hint=access_token&
client_id=my-app&
client_secret=CLIENT_SECRET
注記:
リフレッシュ トークンを取り消す → リフレッシュ トークンと関連する SSO セッションの両方を無効化します (構成に応じて)
アクセス トークンを取り消す → JWT ベースのトークンの場合、取り消しはリソース サーバーがトークン イントロスペクションを実行するか、トークン取り消しイベントを使用する場合にのみ有効です。
4.2 Not-Beforeポリシー
特定の時間より前に発行されたすべてのトークンを取り消します。
# Set not-before timestamp — tất cả tokens issued trước thời điểm này bị invalidate
PUT /admin/realms/my-company
{
"notBefore": 1711800000 // Unix timestamp
}
# Hoặc qua Admin Console:
# Realm Settings → Sessions → "Set to now" → "Push"
# "Push" gửi not-before policy đến tất cả clients có Admin URL
4.3 トークンのイントロスペクション (RFC 7662)
リソース サーバーは、トークン イントロスペクションを使用してトークンの有効性を検証し、クレームを取得します。
# Introspect token
POST /realms/my-company/protocol/openid-connect/token/introspect
Content-Type: application/x-www-form-urlencoded
token=ACCESS_TOKEN&
client_id=my-resource-server&
client_secret=RESOURCE_SERVER_SECRET
# Response — token hợp lệ
{
"active": true,
"sub": "user-uuid",
"email": "[email protected]",
"realm_access": { "roles": ["admin"] },
"client_id": "my-app",
"token_type": "Bearer",
"exp": 1711800300,
"iat": 1711800000,
"scope": "openid profile email"
}
# Response — token không hợp lệ
{
"active": false
}
トークン イントロスペクションと JWT 検証を使用する場合:
| 方法 | アドバンテージ | 短所 |
|---|---|---|
| JWT 検証 (ローカル) | 高速で、Keycloakを呼び出す必要はありません | リアルタイムなし、失効遅延なし |
| トークンのイントロスペクション (リモート) | リアルタイムのステータス、完全な請求 | ネットワーク遅延、Keycloakへの依存性 |
5. DPoP — 所有証明のデモンストレーション (RFC 9449)
DPoP が問題を解決します無記名トークンの盗難— アクセス トークンが盗まれた場合、トークンとクライアントの間にバインドがないため、攻撃者はどこでもそれを使用できます。
5.1 DPoP はどのように機能しますか?
DPoP はトークンを 1 つにバインドします特定の非対称鍵ペアクライアントが所有するもの。クライアントは、トークンを使用するたびに秘密キーの所有権を証明する必要があります。
┌──────────┐ ┌──────────┐
│ Client │ │ Keycloak │
└────┬─────┘ └────┬─────┘
│ │
│ 1. Generate key pair │
│ (public + private key) │
│ │
│ 2. Token request + │
│ DPoP Proof (signed with │
│ private key) │
│───────────────────────────────>│
│ │
│ 3. DPoP-bound access token │
│ (contains cnf.jkt claim) │
│<──────────────────────────────│
│ │
│ ┌──────────┐
│ │ Resource │
│ │ Server │
│ └────┬─────┘
│ 4. API request + │
│ DPoP-bound token + │
│ DPoP Proof (new, signed │
│ with same private key) │
│──────────────────────────────>│
│ │
│ 5. Verify: token.cnf.jkt │
│ matches DPoP proof's │
│ public key │
│ 6. Response │
│<─────────────────────────────│
5.2 DPoP 耐性のある JWT 構造
// DPoP Proof Header { "typ": "dpop+jwt", "alg": "ES256", "jwk": { "kty": "EC", "crv": "P-256", "x": "base64url-encoded-x", "y": "base64url-encoded-y" } }
// DPoP Proof Payload { "jti": "unique-proof-id", // Unique ID, ngăn replay attacks "htm": "POST", // HTTP method "htu": "https://keycloak/token", // HTTP URI (token endpoint) "iat": 1711800000, // Issued at "ath": "access-token-hash" // Hash of access token (khi gọi resource server) }
5.3 KeycloakでのDPoPの構成
DPoP は次の方法で適用されます。クライアントポリシー:
作成するクライアントプロフィール:
- レルム設定 → クライアントポリシー → プロファイルタブ → 作成
- 名前:
dpop プロファイル - エグゼキュータを追加:DPoP 証明の検証
作成するクライアントポリシー:
- 「ポリシー」タブ→「作成」
- 名前:
dpop ポリシー - 条件を追加します:クライアントアクセスタイプまたはあらゆるクライアント
- アソシエイトプロフィール:
dpop プロファイル
# Token request với DPoP
POST /realms/my-company/protocol/openid-connect/token
Content-Type: application/x-www-form-urlencoded
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik...
grant_type=authorization_code&
code=AUTH_CODE&
client_id=my-app&
redirect_uri=http://localhost:3000/callback
# Response — DPoP-bound token
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "DPoP", // Token type = "DPoP" thay vì "Bearer"
"expires_in": 300
}
# Access token chứa confirmation claim
{
"cnf": {
"jkt": "thumbprint-of-client-public-key" // JWK Thumbprint
}
}
# Gọi Resource Server với DPoP token
GET /api/resource
Authorization: DPoP eyJhbGciOiJSUzI1NiIs...
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIs... # DPoP proof mới (htm=GET, htu=API URL)
5.4 DPoP ナンス
Keycloakは、リプレイ攻撃に対するセキュリティを強化するために、サーバー発行のDPoP nonceをサポートしています。
# Server response header khi DPoP nonce required
HTTP/1.1 401 Unauthorized
DPoP-Nonce: server-generated-nonce
# Client PHẢI include nonce trong DPoP proof tiếp theo
{
"typ": "dpop+jwt",
"alg": "ES256",
"jwk": { ... }
}
{
"jti": "new-unique-id",
"htm": "POST",
"htu": "https://keycloak/token",
"iat": 1711800001,
"nonce": "server-generated-nonce" // Server-issued nonce
}
5.5 DPoP実装例(JavaScript)
// Tạo DPoP key pair const keyPair = await crypto.subtle.generateKey( { name: "ECDSA", namedCurve: "P-256" }, true, ["sign", "verify"] );// Export public key cho DPoP proof const publicKey = await crypto.subtle.exportKey("jwk", keyPair.publicKey);
// Tạo DPoP proof JWT function createDPoPProof(method, url, accessToken = null, nonce = null) { const header = { typ: "dpop+jwt", alg: "ES256", jwk: { kty: publicKey.kty, crv: publicKey.crv, x: publicKey.x, y: publicKey.y, }, };
const payload = { jti: crypto.randomUUID(), htm: method, htu: url, iat: Math.floor(Date.now() / 1000), };
// Thêm access token hash khi gọi resource server if (accessToken) { const encoder = new TextEncoder(); const data = encoder.encode(accessToken); const hashBuffer = await crypto.subtle.digest("SHA-256", data); payload.ath = base64url(hashBuffer); }
// Thêm nonce nếu server yêu cầu if (nonce) { payload.nonce = nonce; }
return signJWT(header, payload, keyPair.privateKey); }
// Sử dụng const dpopProof = await createDPoPProof( "POST", "http://localhost:8080/realms/my-company/protocol/openid-connect/token" );
const tokenResponse = await fetch(tokenEndpoint, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded", DPoP: dpopProof, }, body: "grant_type=authorization_code&code=AUTH_CODE&...", });
6. トークンセキュリティのためのクライアントポリシー
クライアント ポリシーを使用すると、トークンに関連するセキュリティ要件を強制できます。
6.1 トークン関連のエグゼキュータ
| 執行者 | 説明する |
|---|---|
| DPoP 証明の検証 | トークンリクエストには DPoP が必要 |
| 鍵の所有者執行者 | 必要なトークン バインディング (MTLS または DPoP) |
| 安全な署名アルゴリズム | 安全なアルゴリズムのみが許可されます (RS256、ES256 など)。 |
| PKCE 執行者 | 認可コードフローにPKCEを要求する |
| 機密クライアント執行者 | クライアント認証が必要です |
| 安全な応答タイプ | 安全な応答タイプのみが許可されます |
| 暗黙的な許可を拒否する | 暗黙的な許可は許可されません |
# Ví dụ: Policy enforce DPoP + PKCE + Secure Algorithm
Profile: high-security-profile
Executors:
- DPoP Proof Verification
- PKCE Enforcer (S256 only)
- Secure Signing Algorithm (RS256, ES256)
- Reject Implicit Grant
- Confidential Client Enforcer
Policy: high-security-policy
Conditions:
- Client Role: has role "high-security"
Profiles:
- high-security-profile
7. 練習問題
ラボ 1: クライアント スコープ
クライアントスコープの作成
組織マッパーを使用: org_id、org_name、org_role最初にデフォルトとしてスコープをクライアントに割り当て、次にオプションに変更します。
テスト: リクエスト トークンにスコープ パラメーターがない → 組織クレームがない
テスト: トークンをリクエストする
スコープ=オープンID組織→組織の主張がある使用評価するトークンをプレビューするツール
ラボ 2: トークンのライフサイクル
アクセストークン構成の有効期間 = 1 分
リフレッシュ トークンの取り消しをオンにし、リフレッシュ トークンの最大再利用 = 0
トークンを取得→1分待つ→APIを呼び出す→401を取得
トークンを更新 → 新しいトークンを受け取る → API を呼び出す → 成功
古いトークンを更新しようとすると、エラーが発生します(取り消し)
ラボ 3: オフライン アクセス
スコープの割り当て
オフラインアクセスクライアントのためにトークンを取得する
スコープ=openid offline_accessチェック
リフレッシュ_有効期限_in= 0 (オフライントークン)Keycloakを再起動→オフライントークンを使用して更新→引き続き動作
管理コンソールでオフライン セッションを表示する
ラボ 4: DPoP
クライアントに DPoP を強制するクライアント ポリシーを作成する
dpopクライアントキーペアの生成、DPoP 証明 JWT の作成
DPoP ヘッダーを含むトークンを要求 → DPoP バインドされたトークンを受信
トークンを使用してリソースサーバーを呼び出しますが、利用不可DPoP 証明 → リソース サーバー拒否
トークンを使用してリソースサーバーを呼び出すそしてDPoP 証明 → 成功
ラボ 5: トークンの取り消し
アクセストークンとリフレッシュトークンを取得する
取り消しエンドポイント経由でリフレッシュトークンを取り消す
更新してみる→エラーが発生する
「Admin Console」→「Push」で「Not-Before」ポリシーを設定します。
古いアクセス トークンを使用してみる → イントロスペクション トークンが返される
アクティブ=偽