メインコンテンツまでスキップ

認可リクエスト検証フロー詳細

認可エンドポイントにおけるリクエスト検証の全体像を記述する。

全体フロー概要

HTTP Request

[1] OAuthRequestHandler.handleRequest()

[2] OAuthRequestParameters.analyzePattern()
→ NORMAL | REQUEST_OBJECT | REQUEST_URI | PUSHED_REQUEST_URI

[3] ContextCreator.create()
├─ JOSE解析 (Request Object/URIパターンのみ)
├─ filterScopes() → スコープ抽出
└─ analyze() → プロファイル決定

[4] OAuthRequestVerifier.verify()
├─ [4a] baseVerifier.verify() ← プロファイル別
└─ [4b] extensionVerifiers.forEach(verify()) ← 共通拡張

[5] OAuthRequestErrorHandler (エラー時)
├─ OAuthBadRequestException → エラーページ表示
└─ OAuthRedirectableBadRequestException → redirect_uriへリダイレクト

1. リクエストパターン決定

ファイル: libs/idp-server-core/.../oauth/request/OAuthRequestParameters.java

リクエストパラメータから以下の優先順位でパターンを決定:

優先度条件パターン
1requestパラメータありREQUEST_OBJECT
2request_uriがPAR形式PUSHED_REQUEST_URI
3request_uriありREQUEST_URI
4上記以外NORMAL

2. コンテキスト作成

ファイル: libs/idp-server-core/.../oauth/context/OAuthRequestContextCreators.java

パターンごとに異なるCreatorが使用される:

パターンCreatorJOSE処理
NORMALNormalPatternContextCreatorなし(空JoseContext)
REQUEST_OBJECTRequestObjectPatternContextCreatorJWT解析・署名検証
REQUEST_URIRequestUriPatternContextCreatorURIからJWT取得・解析・署名検証
PUSHED_REQUEST_URIPushedRequestUriPatternContextCreatorリポジトリから取得(JOSE不要)

2.1 Request Objectパターンの処理フロー

ファイル: libs/idp-server-core/.../oauth/context/RequestObjectPatternContextCreator.java

JoseHandler.handle(request_jwt, clientJwks, serverJwks, secret)

JoseType.parse(jwt_header)
├─ alg: "none" → JoseType.plain → JwtContextCreator → 空JsonWebSignature
├─ alg: JWS系 → JoseType.signature → JwsContextCreator → 署名検証可能
└─ alg: JWE系 → JoseType.encryption → JweContextCreator → 復号処理

joseContext.verifySignature()
├─ hasJsonWebSignature() == true → 署名検証実行
└─ hasJsonWebSignature() == false → no-op (alg:none)

RequestObjectValidator.validate(claims)

filterScopes() → analyze() → AuthorizationProfile決定

重要: alg: noneの場合、verifySignature()はno-opとなり、isUnsignedRequestObject()がtrueを返す。FAPI AdvancedではFapiAdvanceVerifierがこれを検出して拒否する。

2.2 スコープフィルタリング

ファイル: libs/idp-server-core/.../oauth/context/OAuthRequestContextCreator.java filterScopes()

String targetScope;
if (pattern.isRequestParameter() || clientConfiguration.isSupportedJar()) {
targetScope = joseScope; // Request Object内のscope
} else {
targetScope = queryScope; // クエリパラメータのscope
}
return clientConfiguration.filteredScope(targetScope);
パターンスコープ取得元
REQUEST_OBJECT / REQUEST_URIJWT claims内のscope
NORMALクエリパラメータのscope
PUSHED_REQUEST_URIPAR時に保存済みのスコープ

注意: Request ObjectパターンでscopeがJWT内に含まれていない場合、joseScopeは空文字列/nullとなり、フィルタ結果も空になる。

2.3 プロファイル決定

ファイル: libs/idp-server-core/.../oauth/context/OAuthRequestContextCreator.java analyze()

フィルタ済みスコープから以下の優先順位でプロファイルを決定:

優先度条件プロファイル
1テナント設定のfapi_advance_scopesに該当FAPI_ADVANCE
2テナント設定のfapi_baseline_scopesに該当FAPI_BASELINE
3openidスコープを含むOIDC
4上記以外OAUTH2

重要: スコープが空の場合、プロファイルはOAUTH2に解決される。これにより、Request Object内にscopeがない場合にFAPI検証が実行されない問題が発生する(GAP-006参照)。

3. 検証チェーン

ファイル: libs/idp-server-core/.../oauth/verifier/OAuthRequestVerifier.java

public void verify(OAuthRequestContext context) {
// [Step 1] プロファイル別base verifier
AuthorizationRequestVerifier baseVerifier = baseVerifiers.get(context.profile());
baseVerifier.verify(context);

// [Step 2] 拡張verifier(条件付き)
extensionVerifiers.forEach(verifier -> {
if (verifier.shouldVerify(context)) {
verifier.verify(context);
}
});
}

3.1 Base Verifier一覧

プロファイルBase Verifier内部呼び出し
OAUTH2OAuth2RequestVerifierOAuthRequestBaseVerifier
OIDCOidcRequestVerifierOidcRequestBaseVerifierOAuthRequestBaseVerifier
FAPI_BASELINEFapiBaselineVerifier (plugin)OidcRequestBaseVerifier or OAuthRequestBaseVerifier
FAPI_ADVANCEFapiAdvanceVerifier (plugin)OidcRequestBaseVerifier or OAuthRequestBaseVerifier

3.2 Extension Verifier一覧

Extension VerifiershouldVerify()条件
RequestObjectVerifierisRequestParameterPattern() && !isUnsignedRequestObject()
OAuthAuthorizationDetailsVerifierhasAuthorizationDetails()
JarmVerifierresponseMode().isJwtMode()

注意: RequestObjectVerifierisUnsignedRequestObject()がtrueの場合(alg: none)スキップされる。

4. Base Verifier詳細

4.1 OAuthRequestBaseVerifier(OAuth 2.0基本検証)

ファイル: libs/idp-server-core/.../oauth/verifier/base/OAuthRequestBaseVerifier.java

検証エラーコード例外型
response_type必須invalid_requestRedirectable
response_type有効値invalid_requestRedirectable
サーバー対応response_typeunsupported_response_typeRedirectable
クライアント対応response_typeunauthorized_clientRedirectable
スコープ存在invalid_scopeRedirectable

4.2 OidcRequestBaseVerifier(OIDC検証)

ファイル: libs/idp-server-core/.../oauth/verifier/base/OidcRequestBaseVerifier.java

OAuthRequestBaseVerifierの検証を含み、追加で以下を検証:

検証エラーコード例外型
redirect_uri必須invalid_requestNon-redirectable
redirect_uri絶対URIinvalid_requestNon-redirectable
redirect_uri登録済みinvalid_requestNon-redirectable
Implicit Flowでhttp禁止invalid_requestRedirectable
Implicit/Hybrid Flowでnonce必須invalid_requestRedirectable
OAuthRequestBaseVerifier.verify()(上記参照)
display有効値invalid_requestRedirectable
prompt有効値invalid_requestRedirectable
prompt=none単独invalid_requestRedirectable
max_age有効値invalid_requestRedirectable

4.3 FapiBaselineVerifier

ファイル: libs/idp-server-core-extension-fapi/.../fapi/FapiBaselineVerifier.java

検証エラーコード例外型仕様参照
redirect_uri登録済みinvalid_requestNon-redirectable5.2.2-8
redirect_uri必須invalid_requestNon-redirectable5.2.2-9
redirect_uri完全一致invalid_requestNon-redirectable5.2.2-10
redirect_uri https必須invalid_requestNon-redirectable5.2.2-20
OidcRequestBaseVerifier.verify() or OAuthRequestBaseVerifier.verify()
client_secret_post/basic禁止unauthorized_clientRedirectable5.2.2-4
PKCE S256必須invalid_requestRedirectable5.2.2-7
openidスコープ時nonce必須invalid_requestRedirectable5.2.2.2-1
非openidスコープ時state必須invalid_requestRedirectable5.2.2.3-1

4.4 FapiAdvanceVerifier

ファイル: libs/idp-server-core-extension-fapi/.../fapi/FapiAdvanceVerifier.java

検証エラーコード例外型仕様参照
JARM設定確認(JWT mode時)unauthorized_clientNon-redirectable-
OidcRequestBaseVerifier.verify() or OAuthRequestBaseVerifier.verify()
Request Objectパターン必須invalid_requestRedirectable5.2.2-1
alg:none拒否invalid_request_objectRedirectable5.2.2-1
response_type: code id_token or code+jwtinvalid_requestRedirectable5.2.2-2
sender-constrained access token必須invalid_requestRedirectable5.2.2-5
exp-nbf ≤ 60分invalid_request_objectRedirectable5.2.2-13
aud含むissuerinvalid_request_objectRedirectable5.2.2-15
client_secret_*系禁止unauthorized_clientRedirectable5.2.2-14
publicクライアント禁止unauthorized_clientRedirectable5.2.2-16
nbf 60分以内invalid_request_objectRedirectable5.2.2-17

5. Extension Verifier詳細

5.1 RequestObjectVerifier → RequestObjectVerifyable

ファイル: libs/idp-server-core/.../oauth/verifier/extension/RequestObjectVerifier.java ファイル: libs/idp-server-core/.../oauth/verifier/extension/RequestObjectVerifyable.java

実行条件: isRequestParameterPattern() && !isUnsignedRequestObject()

検証エラーコード仕様参照
対称鍵(HS*)拒否invalid_request_object-
iss = client_idinvalid_request_object-
aud含むissuerinvalid_request_object-
jti(任意、検証なし)-FAPI 1.0では任意
exp存在・有効期限内invalid_request_object-
scope存在(require_signed_request_object時)invalid_request_objectRFC 9101 §6.3, FAPI 5.2.2-13

5.2 JarmVerifier

ファイル: libs/idp-server-core/.../oauth/verifier/extension/JarmVerifier.java

実行条件: responseMode().isJwtMode()

検証エラーコード
form_post.jwt非対応unauthorized_client

6. エラーハンドリング

ファイル: libs/idp-server-core/.../oauth/handler/OAuthRequestErrorHandler.java

6.1 例外型とルーティング

例外型レスポンス動作
OAuthBadRequestExceptionBAD_REQUESTエラーページ表示(リダイレクト不可)
OAuthRedirectableBadRequestExceptionREDIRECTABLE_BAD_REQUESTredirect_uriへエラーリダイレクト
ClientUnAuthorizedExceptionBAD_REQUESTinvalid_client
ClientConfigurationNotFoundExceptionBAD_REQUESTinvalid_request
ServerConfigurationNotFoundExceptionBAD_REQUESTinvalid_request
その他SERVER_ERRORserver_error

6.2 エラーレスポンス生成

ファイル: libs/idp-server-core/.../oauth/response/AuthorizationErrorResponseCreator.java

OAuthRedirectableBadRequestExceptionの場合、AuthorizationErrorResponseCreatorがリダイレクトURLを構築:

redirect_uri?error=xxx&error_description=xxx&state=xxx

JARMラップ条件: context.responseMode().isJwtMode()のみ。プロファイルベースの自動JARM判定(context.isJwtMode())はエラーレスポンスには使用しない。リクエスト自体が不正(例: response_type=code without response_mode=jwt)な場合、エラーはplain query parameterで返す必要があるため。

7. 既知のギャップと注意点

7.1 スコープ欠落時のプロファイル解決問題

Request Object内にscopeが含まれない場合:

  1. filterScopes()joseScopeが空 → フィルタ結果も空
  2. analyze()でプロファイルがOAUTH2に解決
  3. FapiAdvanceVerifierが実行されない
  4. OAuthRequestBaseVerifier.throwExceptionIfNotContainsValidScope()invalid_scopeをスロー
  5. RequestObjectVerifyable.throwExceptionIfMissingScopeWhenRequired()に到達しない

対策: RequestObjectPatternContextCreatorでプロファイル解決前にscope存在チェックを行う必要がある(GAP-006参照)。

7.2 alg:none Request Objectの処理

alg: noneのRequest Objectは:

  1. JoseType.plainとして処理 → 空JsonWebSignature
  2. isUnsignedRequestObject() = true
  3. RequestObjectVerifierがスキップ(shouldVerify = false)
  4. FapiAdvanceVerifierthrowExceptionIfNotRRequestParameterPattern()で検出・拒否

7.3 実行順序の重要性

[先] base verifier (profile-specific)
├─ OAuthRequestBaseVerifier.throwExceptionIfNotContainsValidScope() → invalid_scope
├─ FapiAdvanceVerifier.throwExceptionIfNotRRequestParameterPattern() → invalid_request_object
└─ ...
[後] extension verifier
└─ RequestObjectVerifier → RequestObjectVerifyable.verify() → invalid_request_object

base verifierが先に実行されるため、base verifierでのエラーがextension verifierのエラーを覆い隠す場合がある。

8. ファイル一覧

コンポーネントファイルパス
パターン決定libs/idp-server-core/.../oauth/request/OAuthRequestParameters.java
Creator管理libs/idp-server-core/.../oauth/context/OAuthRequestContextCreators.java
Normalパターンlibs/idp-server-core/.../oauth/context/NormalPatternContextCreator.java
Request Objectパターンlibs/idp-server-core/.../oauth/context/RequestObjectPatternContextCreator.java
Request URIパターンlibs/idp-server-core/.../oauth/context/RequestUriPatternContextCreator.java
Pushed URIパターンlibs/idp-server-core/.../oauth/context/PushedRequestUriPatternContextCreator.java
プロファイル解析libs/idp-server-core/.../oauth/context/OAuthRequestContextCreator.java
検証チェーンlibs/idp-server-core/.../oauth/verifier/OAuthRequestVerifier.java
OAuth2 base検証libs/idp-server-core/.../oauth/verifier/base/OAuthRequestBaseVerifier.java
OIDC base検証libs/idp-server-core/.../oauth/verifier/base/OidcRequestBaseVerifier.java
OAuth2 verifierlibs/idp-server-core/.../oauth/verifier/OAuth2RequestVerifier.java
OIDC verifierlibs/idp-server-core/.../oauth/verifier/OidcRequestVerifier.java
FAPI Baselinelibs/idp-server-core-extension-fapi/.../fapi/FapiBaselineVerifier.java
FAPI Advancedlibs/idp-server-core-extension-fapi/.../fapi/FapiAdvanceVerifier.java
Request Object検証libs/idp-server-core/.../oauth/verifier/extension/RequestObjectVerifier.java
Request Object検証IFlibs/idp-server-core/.../oauth/verifier/extension/RequestObjectVerifyable.java
JARM検証libs/idp-server-core/.../oauth/verifier/extension/JarmVerifier.java
AuthDetails検証libs/idp-server-core/.../oauth/verifier/extension/OAuthAuthorizationDetailsVerifier.java
JOSE処理libs/idp-server-platform/.../jose/JoseHandler.java
JOSE型判定libs/idp-server-platform/.../jose/JoseType.java
未署名JWTlibs/idp-server-platform/.../jose/JwtContextCreator.java
署名JWTlibs/idp-server-platform/.../jose/JwsContextCreator.java
エラー処理libs/idp-server-core/.../oauth/handler/OAuthRequestErrorHandler.java
エラーレスポンス生成libs/idp-server-core/.../oauth/response/AuthorizationErrorResponseCreator.java
Deny エラーレスポンスlibs/idp-server-core/.../oauth/response/AuthorizationDenyErrorResponseCreator.java
ResponseMode判定libs/idp-server-core/.../oauth/response/ResponseModeDecidable.java