원클릭으로
spec-token
トークン管理(Token Management)機能の開発・修正を行う際に使用。Access Token, Refresh Token, ID Token, Introspection, Revocation実装時に役立つ。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
トークン管理(Token Management)機能の開発・修正を行う際に使用。Access Token, Refresh Token, ID Token, Introspection, Revocation実装時に役立つ。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
UserInfoエンドポイント(UserInfo Endpoint)機能の開発・修正を行う際に使用。UserInfo claims、scopeフィルタリング、verified_claims実装時に役立つ。
外部API認証ユースケースの設定ガイド。外部API連携(認証委譲、リスク判定、OTP等)の interaction 設計、identity_match_field、MFA 2段階目、previous_interaction のヒアリングと設定JSONを提供。
ユースケース別セットアップのエントリポイント。ユーザーにユースケースを選択してもらい、対応するスキル(use-case-login, use-case-mfa等)にルーティングする。共通ワークフロー、前提条件、組み合わせパターンの概要を提供。
認証機能(Authentication Policy, MFA)の開発・修正を行う際に使用。認証ポリシー、パスワード、OTP、FIDO2、条件付き認証実装時に役立つ。
セキュリティ・脆弱性対策の開発・テストを行う際に使用。OAuth/OIDC攻撃対策、認証識別子切り替え攻撃、Session Fixation、マルチテナント分離、セキュリティテスト実装時に役立つ。
外部サービス連携(External Service Integration)機能の開発・修正を行う際に使用。HTTP Request Executor, MappingRule, OAuth/HMAC認証実装時に役立つ。
| name | spec-token |
| description | トークン管理(Token Management)機能の開発・修正を行う際に使用。Access Token, Refresh Token, ID Token, Introspection, Revocation実装時に役立つ。 |
documentation/docs/content_06_developer-guide/03-application-plane/03-token-endpoint.md - トークンエンドポイント実装ガイドdocumentation/docs/content_03_concepts/04-tokens-claims/concept-02-token-management.md - トークン管理概念documentation/docs/content_05_how-to/phase-2-security/02-token-strategy.md - トークン有効期限パターン(4パターン、クライアントレベルオーバーライド)documentation/docs/content_07_reference/transaction-expiration-settings.md - トランザクションデータの有効期限設定リファレンスdocumentation/docs/content_06_developer-guide/05-configuration/client.md - Client設定ガイド(Extension設定のトークン関連項目)トークン管理は、Access Token/Refresh Token/ID Tokenの発行・検証・取消を行う層。
libs/
├── idp-server-core/ # トークンコア
│ └── .../token/
│ ├── handler/token/
│ │ └── TokenRequestHandler.java # トークンリクエスト処理
│ ├── service/
│ │ ├── OAuthTokenCreationServices.java
│ │ ├── AuthorizationCodeGrantService.java
│ │ ├── RefreshTokenGrantService.java
│ │ └── ClientCredentialsGrantService.java
│ ├── OAuthToken.java # トークン表現
│ ├── repository/
│ │ ├── OAuthTokenCommandRepository.java
│ │ └── OAuthTokenQueryRepository.java
│ └── handler/
│ ├── tokenintrospection/
│ │ └── TokenIntrospectionHandler.java
│ └── tokenrevocation/
│ └── TokenRevocationHandler.java
│
├── idp-server-core-adapter/ # アダプター(キャッシュ含む)
│ └── .../datasource/token/
│ ├── OAuthTokenCacheKeyBuilder.java # キャッシュキー生成(共有)
│ ├── OAuthTokenCacheStoreResolver.java # TOKEN_CACHE_ENABLED制御
│ ├── command/
│ │ └── OAuthTokenCommandDataSource.java # 削除時キャッシュ連動
│ └── query/
│ └── OAuthTokenQueryDataSource.java # Introspection時キャッシュ
│
└── idp-server-control-plane/ # 管理API
└── .../management/token/
└── TokenConfigManagementApi.java
idp-server-core/token/handler/token/TokenRequestHandler.java 内の実際のメソッドシグネチャ:
public class TokenRequestHandler {
OAuthTokenCreationServices oAuthTokenCreationServices;
public TokenRequestResponse handle(
TokenRequest tokenRequest,
PasswordCredentialsGrantDelegate passwordCredentialsGrantDelegate,
TokenUserFindingDelegate tokenUserFindingDelegate
) {
// Grant typeに応じた処理はOAuthTokenCreationServicesが管理
// AuthorizationCodeGrantService
// RefreshTokenGrantService
// ClientCredentialsGrantService
// ...
}
}
注意: Grant type別の処理は、OAuthTokenCreationServices経由で各Serviceに委譲されます。
| サービス | 役割 |
|---|---|
AuthorizationCodeGrantService | Authorization Code Grant処理 |
RefreshTokenGrantService | Refresh Token Grant処理 |
ClientCredentialsGrantService | Client Credentials Grant処理 |
JwtBearerGrantService | JWT Bearer Grant処理(RFC 7523) |
JWT Bearer Grantは、JWTアサーションを使用してアクセストークンを直接取得するグラントタイプです。
urn:ietf:params:oauth:grant-type:jwt-bearer| タイプ | 説明 | 署名検証 |
|---|---|---|
device | デバイスシークレットによる認証 | HMAC(HS256/HS384/HS512) |
| 外部IdP | 外部OIDCプロバイダーのトークン | RSA/EC(jwks_uri取得) |
{
"grant_types": ["urn:ietf:params:oauth:grant-type:jwt-bearer"],
"extension": {
"available_federations": [
{
"issuer": "device",
"type": "device",
"jwt_bearer_grant_enabled": true
},
{
"issuer": "https://accounts.google.com",
"provider_id": "google",
"type": "oidc",
"jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
"jwt_bearer_grant_enabled": true
}
]
}
}
POST /v1/tokens
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <base64(client_id:client_secret)>
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
&assertion=<JWT>
&scope=openid profile
// Header
{
"alg": "HS256",
"typ": "JWT"
}
// Payload
{
"iss": "device:{deviceId}",
"sub": "{deviceId}",
"aud": "https://idp.example.com/{tenantId}",
"jti": "unique-token-id",
"iat": 1234567890,
"exp": 1234571490
}
JWTのsubクレームからユーザーを解決する方法を設定できます。
| subject_claim_mapping | 動作 | デフォルト |
|---|---|---|
device_id | subをデバイスIDとして扱い、デバイス所有者を検索 | デバイスフェデレーション |
sub | subをidp-serverのユーザーIDとして直接検索 | - |
email | subをメールアドレスとして検索 | - |
| (default) | subを外部IdPのユーザー識別子として検索 | 外部IdPフェデレーション |
外部IdPフェデレーションの動作:
subは外部IdPでのユーザー識別子(idp-serverのユーザーIDではない)findByExternalIdpSubject(tenant, subject, providerId)で検索providerIdはフェデレーション設定のprovider_idから取得(未設定の場合はissuerにフォールバック)provider_id設定:
{
"issuer": "https://accounts.google.com",
"provider_id": "google", // ユーザー検索時に使用(DDL制約対応)
"type": "oidc"
}
provider_idを明示的に設定することで、長いissuer URLではなく短い識別子でユーザー検索が可能VARCHAR(255)制約に対応issuerがそのまま使用される(後方互換性)セキュリティ上の利点(device_id方式):
| ファイル | 役割 |
|---|---|
JwtBearerGrantService.java | JWT Bearer Grant処理メイン |
JwtBearerGrantValidator.java | リクエスト検証 |
JwtBearerGrantVerifier.java | JWTクレーム検証 |
JwtBearerUserFinder.java | ユーザー解決ロジック |
JwtBearerUserFindingDelegate.java | ユーザー検索インターフェース |
idp-server-core/token/introspection/ 内:
トークンのメタデータを検証し、active/inactiveを返却します。
Redis有効時、OAuthToken の DB row を Redis にキャッシュします(デフォルト有効)。
oauth_token:at:{tenant_id}:{hmac(access_token)}(OAuthTokenCacheKeyBuilderで生成)OAuthTokenCacheStoreResolver.TOKEN_CACHE_TTL_SECONDS)TOKEN_CACHE_ENABLED=false を設定した場合のみ NoOperationCacheStore に切替。Redis 無効(CACHE_ENABLE=false)時は自動的に no-op に縮退| トリガー | 経路 | 備考 |
|---|---|---|
発行 (OAuthTokenCommandDataSource.register) | writer での INSERT 直後に write-through | OAuthTokenRowBuilder が INSERT params 構築と並行に row map を作るため追加 SELECT なし。reader のレプリケーション遅延を踏まずに直後の introspection を Redis hit にできる |
Introspection の cache miss → DB hit (OAuthTokenQueryDataSource.find) | reader での SELECT 後に cache-aside で put | TTL 経過後の再格納パス |
トークンが削除される全パターンでキャッシュも連動して削除されます:
| 削除トリガー | 処理 |
|---|---|
| Token Revocation | DB DELETE + キャッシュ削除 |
| 認可グラント削除(管理API) | GrantRevocationService → deleteByUserAndClient → SELECT hashed tokens → キャッシュ削除 → DB DELETE |
| ログアウト等の一括失効 | deleteByUserAndClient → SELECT hashed tokens → キャッシュ削除 → DB DELETE |
| TTL経過 | キャッシュ自動削除(60秒) |
idp-server-core/token/revocation/ 内:
トークンを無効化します。OAuthTokenCommandRepository.delete()を使用します。キャッシュが有効な場合、DB削除と同時にキャッシュも削除されます。
authorization_server.extension.access_token_type で制御(認可サーバーレベルの設定。クライアント単位のオーバーライドは不可)。
| タイプ | 形式 | 検証方法 | Revocation反映 |
|---|---|---|---|
| opaque(デフォルト) | ランダム文字列 | Introspectionエンドポイント必須 | 即時(DB削除) |
| JWT | header.payload.signature | JWKS署名検証でローカル検証可能 | 次回Introspection時(JWTは自己完結型のため即時反映されない) |
使い分けの指針:
JWTの場合、ペイロードに iss, sub, scope, client_id, exp 等が含まれる。JWKSエンドポイント(/v1/jwks)で公開鍵を取得して署名検証する。Introspectionも引き続き動作する。
RefreshTokenCreatable が以下の4パターンで動作する。
| strategy | rotation | トークン値 | 有効期限 |
|---|---|---|---|
| EXTENDS | true | 新しい | 延長(now + duration) |
| EXTENDS | false | 同じ | 延長(now + duration) |
| FIXED | true | 新しい | 同じ(初回発行時のまま) |
| FIXED | false | 同じ | 同じ(初回発行時のまま) |
{
"extension": {
"refresh_token_duration": 604800,
"refresh_token_strategy": "FIXED",
"rotate_refresh_token": true
}
}
rotate_refresh_token: true: リフレッシュ時に新しいRTを発行し、旧RTを無効化する。旧RTでのリフレッシュはエラーrotate_refresh_token: false: 同じRTを繰り返し使えるnow + duration にリセットされる。アクティブなユーザーはログアウトされない認可サーバー設定(authorization_server.extension)でデフォルト値を設定し、クライアント設定で個別にオーバーライド可能。
| 設定 | デフォルト | 説明 |
|---|---|---|
access_token_duration | 3600 | AT有効期限(秒) |
id_token_duration | 3600 | ID Token有効期限(秒)。IdTokenCreatorがnow + durationでexpを計算 |
refresh_token_duration | 604800 | RT有効期限(秒) |
authorization_code_valid_duration | 600 | 認可コード有効期限(秒)。RFC 6749推奨は最大10分 |
oauth_authorization_request_expires_in | 1800 | 認可リクエスト(認証中コンテキスト)の有効期限。AUTH_SESSION cookieのmaxAgeと同じ値が使われる |
authorization_server.extension.id_token_strict_mode で ID Token に含めるクレームを制御する。
| 条件 | ID Token | UserInfo |
|---|---|---|
false(デフォルト) | scopeベースのクレームを含む(name, email等) | 含む |
true, claims未指定 | sub, iss, aud, exp, iat のみ | 含む |
true, claimsパラメータでessential: true | 指定されたクレームを含む | 含む |
true, claimsパラメータでvoluntary(essentialなし) | 含まない | 含む |
claims:* カスタムスコープへの影響: id_token_strict_mode はID Tokenのみに影響し、UserInfoには影響しない。claims:* カスタムクレームもUserInfoからは通常通り返却される。
| 設定 | 影響範囲 | 動作 |
|---|---|---|
scopes_supported | Discovery(.well-known/openid-configuration)の表示のみ | 実際のスコープ処理には影響しない。スコープのフィルタリングはクライアント設定のscopeで行う |
claims_supported | Grant作成時のフィルタリング | GrantIdTokenClaims/GrantUserinfoClaimsの作成時にclaims_supportedに含まれないクレームを除外する。UserInfo/ID Tokenの両方に影響 |
カスタムスコープとUserInfoの関係: api:read等のリソースアクセス用スコープはUserInfoのクレームに影響しない。UserInfoで返るクレームはprofile, email等のOIDC標準スコープで制御される。
e2e/src/tests/
├── spec/
│ ├── rfc6749_token_endpoint_*.test.js # OAuth 2.0 Token Endpoint
│ ├── rfc7009_token_revocation_*.test.js # Token Revocation
│ ├── rfc7662_token_introspection_*.test.js # Token Introspection
│ ├── rfc7523_jwt_bearer_grant_*.test.js # JWT Bearer Grant
│ └── oidc_core_*.test.js # OIDC関連トークンテスト
│
├── usecase/device-credential/
│ └── device-credential-04-device-secret-issuance.test.js # デバイスシークレット+JWT Bearer
│
└── scenario/application/
└── (トークン関連シナリオテスト)
# ビルド
./gradlew :libs:idp-server-core:compileJava
# テスト
cd e2e && npm test -- spec/rfc6749_token_endpoint_*.test.js
cd e2e && npm test -- spec/rfc7009_token_revocation_*.test.js
cd e2e && npm test -- spec/rfc7662_token_introspection_*.test.js
cd e2e && npm test -- spec/rfc7523_jwt_bearer_grant_*.test.js
cd e2e && npm test -- usecase/device-credential/device-credential-04-device-secret-issuance.test.js
TOKEN_CACHE_ENABLED=falseが環境変数に設定されていないか確認(デフォルトは有効)CACHE_ENABLE=true(Redis自体)が有効か確認OAuthTokenCacheStoreResolverがNoOperationCacheStoreを返していないか確認available_federationsにtype: "device"が含まれているか確認jwt_bearer_grant_enabled: trueが設定されているか確認algがデバイス設定と一致しているか確認(HS256/HS384/HS512)subクレームにデバイスIDが設定されているか確認subject_claim_mappingの設定を確認(デフォルト: device_id)