HTTP認証スキームをケースインセンシティブにマッチさせる

rails/rails

Token と Bearer の認証スキームが、HTTP Authorization ヘッダーの auth‑scheme 部分を大文字小文字を区別せずに判定するようになり、RFC 9110 に準拠した動作になります。

背景

現在の実装では TokenBearer の認証スキームがケースセンシティブに比較されていたため、bearer abc123 のように小文字で送られたヘッダーはトークンが取得できず、認証が失敗して 401 応答が返されました。 Token モジュールの TOKEN_REGEXActionDispatch::Request#bearer_token が大文字のみを許容していたことが根本原因です。これにより、実運用で広く見られる小文字表記が正しく処理されませんでした。

RFC 9110 §11.1 では auth‑scheme がケースインセンシティブであることが規定されています。実際のクライアントやプロキシは bearerTOKEN といった非正規表記を送出することが多く、Rails の Basic 認証モジュールはすでにケースインセンシティブで比較していますが、Token と Bearer だけが例外となっていました。この不整合が認証失敗の原因となっていたため、統一的な挙動へ修正する必要がありました。

ケースセンシティブな比較は認証フロー全体で失敗の原因となっていたため、RFC の要件と他モジュールとの一貫性を保つべく、スキーム比較をケースインセンシティブに変更することが求められました。

技術的な変更

Token モジュールの TOKEN_REGEX にケースインセンシティブフラグ i が追加され、スキーム部分のマッチングが大小文字を無視して行われるようになりました。

変更前:

TOKEN_REGEX = /^(Token|Bearer)\s+/

変更後:

TOKEN_REGEX = /^(Token|Bearer)\s+/i

ActionDispatch::Request#bearer_token メソッドでも同様に正規表現に i フラグが付与され、Authorization ヘッダーからトークンを抽出する際にスキームの大小文字を無視できるようになりました。

変更前:

authorization.to_s[/\ABearer (.+)\z/, 1]

変更後:

authorization.to_s[/\ABearer (.+)\z/i, 1]

テストが追加され、bearer, BEARER, token, TOKEN といった様々な表記で認証が成功することが確認されました。actionpack/test/controller/http_token_authentication_test.rb ではスキームの大小文字を変化させたリクエストがすべて成功し、actionpack/test/dispatch/request_test.rb では bearer_token がケースインセンシティブに動作することを検証しています。

設計判断

ケースインセンシティブ化は既存の Basic モジュールと一貫性を持たせることを目的として実装されました。Basic がすでに正規表現に /i フラグを使用しているため、Token と Bearer にも同様のフラグを付与することで認証スキーム全体で統一された挙動を実現しています。

正規表現フラグの追加のみで実装されたため、TokenBearer の呼び出しロジックやメソッドシグネチャは変更されず、既存コードへの影響は最小限に抑えられました。これにより後方互換性が保たれ、既存アプリケーションが改修なしで新しい挙動を利用できます。

この設計選択により、コードベースへのリスクを抑えつつ RFC 準拠という要件をシンプルに達成したと言えます。

まとめ

TokenBearer の認証スキームがケースインセンシティブにマッチするようになり、HTTP 認証の RFC 準拠が実現されました。正規表現フラグの追加とテスト拡充だけで実装されたため、既存の動作を壊すことなく認証の堅牢性が向上しています。

記事メタデータ

Generated by:
gpt-oss-120b for DiffDaily
LLM Trace:
507d1e15

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
リトライ後承認
Review Count:
2回 (改善を経て承認)
Reviewed by:
gpt-oss-120b for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文、背景、技術的変更、設計判断(任意)、まとめの全要素が揃っており、総論→各論→結論の構成が明確です。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライトが正しい形式で使用され、PRリンクも #番号 の形式で正しくリンク化されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

エンジニア向けの専門的な内容で、不要な初心者向け説明はありません。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが総論・各論・結論の段落に分かれ、段落はトピックセンテンスで始まり、一段落一トピックで適切な長さです。空行で区切られています。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事中のコードブロックはDiffと完全に一致しており、変更内容(i フラグの追加)が正確に反映されています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

「auth‑scheme」「RFC 9110」「正規表現フラグ i」などの用語がPRと一致し、誤用はありません。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

技術的な主張はPRの説明とDiffに裏付けられており、因果関係も論理的です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

全ての主張がPRタイトル、説明、Diffに基づいており、捏造や推測はありません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号 #57990 など数値・固有名詞は正確です。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事タイトルはPRタイトルの内容を日本語で正確に表現しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

RFC 9110 の言及はPRに記載されており、その他外部知識は含まれていません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

時間表現の歪曲はなく、PRの記述と整合しています。