認証アーキテクチャ: BFF Proxy パターン
設計判断
トークン管理を BFF 側に完全移行する BFF Proxy パターン を採用する。
| 観点 | 従来方式(JavaScript 変数) | BFF Proxy パターン(採用) |
|---|---|---|
| Access Token の保存場所 | ブラウザメモリ(JavaScript 変数) | BFF サーバーサイドセッション |
| XSS リスク | JavaScript から Access Token にアクセス可能 | ブラウザに JWT が存在しない |
| ブラウザに渡すもの | Access Token + Refresh Token (Cookie) | HttpOnly Session Cookie のみ |
| トークンリフレッシュ | ブラウザが Refresh Token を送信 | BFF 内部で自動実行 |
| SSO/OIDC 統合 | フロントエンドが OIDC フローを処理 | BFF がリレーパーティとして処理 |
フロー概要
Session Cookie の仕様
| 属性 | 値 | 理由 |
|---|---|---|
HttpOnly | true | JavaScript からのアクセスを防止(XSS 対策) |
Secure | true | HTTPS 通信でのみ送信 |
SameSite | Strict | クロスサイトリクエストでの送信を防止(CSRF 基本対策) |
Path | / | 全ポータルで共有 |
Max-Age | 7日 | Refresh Token と同期 |
トークンリフレッシュ
BFF はリクエスト処理時に Access Token の残り有効期間を確認し、残り2分未満 であれば Refresh Token を用いて事前にリフレッシュを実行する。
- 先行リフレッシュ: リクエスト処理のレイテンシに影響しないよう、リフレッシュ対象のセッションを非同期で更新する。リフレッシュ中は旧 Access Token が引き続き有効
- Refresh Token ローテーション: リフレッシュのたびに Refresh Token も新しいものに置き換える(旧トークンは即時無効化)
- リフレッシュ失敗: Refresh Token が無効化されている場合(管理者による強制ログアウト等)、セッションを破棄し
401 Unauthorizedを返却。SPA はログイン画面にリダイレクト
ログアウトフロー
SSO/OIDC 統合(→ SR-012)
BFF が SAML/OIDC のリレーパーティ(RP)として機能し、IdP との認証フローを処理する。ブラウザからは通常のセッション Cookie アクセスと同じ体験を提供する。
- SAML 2.0: BFF が SP として Assertion を受信・検証。XML 署名検証、NotBefore/NotOnOrAfter によるリプレイ防止
- OIDC: Authorization Code Flow + PKCE 必須。BFF が Authorization Code を Token に交換
- IdP トークンの扱い: IdP の Access Token / ID Token は BFF 内部で保持。TASHIKA 独自の JWT に変換してセッションに保存。IdP トークンの有効期間と TASHIKA セッションは独立管理
- JIT プロビジョニング: SSO 初回ログイン時にユーザーが TASHIKA に存在しない場合、IdP のクレームから自動作成。SCIM との併用時は SCIM を優先
- Single Logout (SLO): SAML LogoutRequest / OIDC Front-Channel Logout に対応。BFF セッションと Refresh Token を連動して無効化
セッションストア
| 方式 | 特性 | 採用時期 |
|---|---|---|
| PostgreSQL(Refresh Token テーブル流用) | 既存インフラで完結。トランザクション整合性。Refresh Token と同一テーブルで管理可能 | MVP |
| 分散キャッシュ(Redis 等) | 高スループット。セッション数が大量になった場合に有効 | スケールアウト時に検討 |
MVP ではセッションデータを既存の Refresh Token テーブルに列追加する形で管理する。セッション数は同時セッション制限(ユーザーあたり最大3)により制御されるため、PostgreSQL で十分なパフォーマンスを確保できる。
CSRF 保護
SameSite=Strict Cookie を基本防御としつつ、Double Submit Cookie パターン を追加する:
- BFF がセッション作成時に CSRF トークン(ランダムな UUID)を生成
- CSRF トークンを 非 HttpOnly の Cookie(
csrf_token、SameSite=Strict; Secure)としてブラウザに設定 - SPA は状態変更リクエスト(POST/PUT/PATCH/DELETE)時に、Cookie から読み取った CSRF トークンを
X-CSRF-Tokenヘッダーに付与 - BFF は Cookie 内の CSRF トークンとヘッダーの値を照合
Cookie: session_id=xxx; csrf_token=yyy
X-CSRF-Token: yyyGET リクエスト(冪等)には CSRF トークン検証を適用しない。