何をしたいか
認可コード / リフレッシュ トークン / Request Object の有効期限を実際に検証する。
併せて Request Object をワンタイムにし、リフレッシュ トークンの再利用を検知する。
なぜ必要か
現状、いずれも有効期限が検証されていない。 ストアには CreatedDate を書いているが、
どこからも読んでいない。
認可コード
AuthenticationCodeDictionary の CreatedDate は未参照。Receive は経過時間を見ずに払い出す。
RFC 6749 §4.1.2 は短命(推奨 10 分以内)を求めている。
Memory Provider の ConcurrentDictionary は未使用の code を回収しないため、
未消費の code がメモリに残り続ける(DBMS 側も行が残る)。
https://github.com/OpenTouryoProject/MultiPurposeAuthSite/blob/develop/root/programs/CommonLibrary/TokenProviders/AuthorizationCodeProvider.cs
リフレッシュ トークン
Config.OAuth2RefreshTokenExpireTimeSpanFromDays(既定 14 日)は
Co/Config.cs の定義以外どこからも参照されていない。 → 事実上の無期限。
https://github.com/OpenTouryoProject/MultiPurposeAuthSite/blob/develop/root/programs/CommonLibrary/Co/Config.cs#L1082-L1088
ローテーション(使用時に削除)は行っているが、
ローテーション済みトークンを再提示されても検知・失効(family revocation)をしない。
OAuth 2.0 Security BCP §4.14 が求める挙動。
また GrantRefreshTokenCredentials は permittedLevel を ClientMode.normal に
ハードコードしているため、FAPI クライアントがリフレッシュすると保証レベルが落ちる。
Request Object(/ros)
署名検証は行っているが、RequestObjectProvider は CreatedDate を書くだけで読まない。
/ros の応答が返す exp は 空文字列。
認可エンドポイントで消費した後も Delete(メソッドは存在する)が呼ばれない。
コード中のコメント「存続期間は短く、好ましくは一回限」がそのまま未実装項目になっている。
https://github.com/OpenTouryoProject/MultiPurposeAuthSite/blob/develop/root/programs/MultiPurposeAuthSiteCore/MultiPurposeAuthSiteCore/Controllers/OAuth2EndpointController.cs#L995
案
- 各 Provider の
Receive / Get で CreatedDate と設定値を突き合わせ、期限切れは空を返す。
- 認可コードの寿命は新しい設定キー(例
AuthorizationCodeExpireTimeSpanFromSeconds、既定 600)を足す。
- リフレッシュ トークンは既存の
OAuth2RefreshTokenExpireTimeSpanFromDays を使う。
- Request Object は新しい設定キーか、
DeviceAuthZExpireTimeSpanFromSeconds に倣った短い固定値。
- Request Object は認可エンドポイントでの消費後に
Delete する。
- リフレッシュ トークンの再利用検知は、削除ではなく「使用済みフラグ+family id」に持ち替える設計が要る。
DDL の変更を伴うため、1 と 2 とは別 PR にした方がよい。
- 期限切れレコードの掃除(バッチ or 参照時削除)も併せて検討する。
影響
利用者への影響: 有り。
- 発行から一定時間が経った認可コード / リフレッシュ トークン /
request_uri が使えなくなる。
長期運用しているリフレッシュ トークンは失効する(既定 14 日)。
- 3 を実施する場合、
RefreshTokenDictionary の DDL 変更が
sqlserver / oracle / pstgrs の 3 方言すべてに必要。
- net48 / net10.0 の両方に効く。
何をしたいか
認可コード / リフレッシュ トークン / Request Object の有効期限を実際に検証する。
併せて Request Object をワンタイムにし、リフレッシュ トークンの再利用を検知する。
なぜ必要か
現状、いずれも有効期限が検証されていない。 ストアには
CreatedDateを書いているが、どこからも読んでいない。
認可コード
AuthenticationCodeDictionaryのCreatedDateは未参照。Receiveは経過時間を見ずに払い出す。RFC 6749 §4.1.2 は短命(推奨 10 分以内)を求めている。
Memory Provider の
ConcurrentDictionaryは未使用の code を回収しないため、未消費の code がメモリに残り続ける(DBMS 側も行が残る)。
https://github.com/OpenTouryoProject/MultiPurposeAuthSite/blob/develop/root/programs/CommonLibrary/TokenProviders/AuthorizationCodeProvider.cs
リフレッシュ トークン
Config.OAuth2RefreshTokenExpireTimeSpanFromDays(既定 14 日)はCo/Config.csの定義以外どこからも参照されていない。 → 事実上の無期限。https://github.com/OpenTouryoProject/MultiPurposeAuthSite/blob/develop/root/programs/CommonLibrary/Co/Config.cs#L1082-L1088
ローテーション(使用時に削除)は行っているが、
ローテーション済みトークンを再提示されても検知・失効(family revocation)をしない。
OAuth 2.0 Security BCP §4.14 が求める挙動。
また
GrantRefreshTokenCredentialsはpermittedLevelをClientMode.normalにハードコードしているため、FAPI クライアントがリフレッシュすると保証レベルが落ちる。
Request Object(
/ros)署名検証は行っているが、
RequestObjectProviderはCreatedDateを書くだけで読まない。/rosの応答が返すexpは 空文字列。認可エンドポイントで消費した後も
Delete(メソッドは存在する)が呼ばれない。コード中のコメント「存続期間は短く、好ましくは一回限」がそのまま未実装項目になっている。
https://github.com/OpenTouryoProject/MultiPurposeAuthSite/blob/develop/root/programs/MultiPurposeAuthSiteCore/MultiPurposeAuthSiteCore/Controllers/OAuth2EndpointController.cs#L995
案
Receive/GetでCreatedDateと設定値を突き合わせ、期限切れは空を返す。AuthorizationCodeExpireTimeSpanFromSeconds、既定 600)を足す。OAuth2RefreshTokenExpireTimeSpanFromDaysを使う。DeviceAuthZExpireTimeSpanFromSecondsに倣った短い固定値。Deleteする。DDL の変更を伴うため、1 と 2 とは別 PR にした方がよい。
影響
利用者への影響: 有り。
request_uriが使えなくなる。長期運用しているリフレッシュ トークンは失効する(既定 14 日)。
RefreshTokenDictionaryの DDL 変更がsqlserver / oracle / pstgrs の 3 方言すべてに必要。