IdPのUI戦略 — Hosted UI vs ヘッドレス、MVC既存アプリからの移行判断

自前OIDCプロバイダーにログインUIを持たせるか、APIだけ提供してRP側で作るか。既存のMVCアプリ(Yii/Rails系)からの移行を想定し、調査項目・トレードオフ・移行パスを整理する。

問い

自前の OIDC プロバイダー (rellf-auth) がある。RP(プロダクト)にログイン機能を提供する際、認証 UI を IdP が持つべきか、RP が持つべきか

既存プロダクトは MVC フレームワーク(Yii / Rails 系)で、POST /login → フレームワーク組み込みの session 開始、という密結合な構造。これを OIDC に移行する際のトレードオフと判断基準を整理する。

2つの選択肢

A. Hosted UI(IdP が UI を持つ)

[RP] GET /login → 302 → [IdP] /oidc/authorize(ログインフォーム表示)
                          ユーザーが認証
                          302 → [RP] /callback?code=xxx
                          RP がセッション開始

IdP がログインフォーム、登録、パスワードリセット等の UI を持つ。Auth0 の Universal Login、Cognito の Hosted UI と同じモデル。

B. ヘッドレス(IdP は API だけ)

[RP] GET /login → RP 自身のログインフォーム表示
     POST /login → RP サーバーが IdP の API を叩いてパスワード検証
                   RP がセッション開始

IdP はトークン発行 API だけ提供し、UI は RP が自由に作る。

トレードオフ比較

観点Hosted UI (A)ヘッドレス (B)
RP 側の実装コスト低(リダイレクトだけ)高(RP ごとにログイン UI を実装)
認証方式追加 (MFA, パスキー)IdP 1箇所の変更で全 RP に反映全 RP のフロントを改修
クレデンシャルの経路IdP にしか送られないRP のフロントを経由する
RP の UI 自由度低(IdP のデザインに縛られる)高(完全にカスタム可能)
既存 URL の維持/login はリダイレクトになる(入口 URL は維持可能)完全に維持できる
ブランディングIdP 側でテーマ対応が必要RP ごとに自由
SSO自然に実現(IdP のセッションを共有)RP ごとに個別実装が必要
セキュリティ監査認証 UI の監査が1箇所RP の数だけ監査対象

調査項目チェックリスト

1. 既存プロダクトの現状

2. プロダクトの数と多様性

3. 認証方式の将来計画

4. セキュリティ要件

5. 移行の制約

判断フロー

プロダクトが1つだけ?
  → YES → ヘッドレスで十分。UI の自由度を取る
  → NO ↓

SSO が必要?
  → YES → Hosted UI 一択(IdP セッション共有が前提)
  → NO ↓

認証方式の追加を頻繁にやる?
  → YES → Hosted UI(1箇所で済む)
  → NO ↓

RP ごとにブランディングが大きく異なる?
  → YES → ヘッドレス or Hosted UI + テーマ機能
  → NO → Hosted UI

MVC フレームワークからの移行パス

既存が MVC フレームワーク(Yii / Rails 系)の場合、Hosted UI 方式の方が移行が小さい

Before

POST /login (email, password)
  → フレームワークの認証機能が DB 直接参照でパスワード検証
  → session_id cookie 発行
  → 以降のリクエストは session_id でユーザー特定

After (Hosted UI)

GET /login → IdP にリダイレクト
GET /callback?code=xxx
  → サーバーサイドで code → token 交換
  → id_token から sub/email 取得
  → フレームワークの session に sub を保存
  → session_id cookie 発行(ここは今と同じ)
  → 以降のリクエストは session_id でユーザー特定(ここも同じ)

変わるもの・変わらないもの

変わる変わらない
ログインの入口✅ IdP にリダイレクト
パスワード検証✅ IdP に委譲
session の仕組み✅ cookie 名、期限、ストアそのまま
current_user ヘルパー✅ session から引くだけ
認可(権限チェック)✅ ログイン後の仕組みは不変
全ページのテンプレート✅ 触らない

やること(最小構成)

  1. /callback エンドポイントを1つ追加(code exchange → session 開始)
  2. 既存の /login を IdP へのリダイレクトに差し替え
  3. 既存のパスワード検証ロジックを削除

触らなくていいもの

MVC フレームワークなら OIDC ライブラリがある

フレームワークライブラリ
Railsomniauth-openid_connect
Yii2yii2-authclient (OpenID Connect)
Laravelsocialite + OIDC provider
Djangomozilla-django-oidc
Springspring-security-oauth2-client

callback の実装もライブラリに任せられるので、RP 側の実装は設定ファイルに issuer URL と client_id/secret を書く程度。

段階的移行の進め方

  1. IdP 側の準備 — rellf-auth の Hosted UI(ログインフォーム)を整備。テーマ対応が必要なら先にやる
  2. 1つのプロダクトで試行 — 最も影響の小さいプロダクトで OIDC 移行。callback エンドポイント追加 + ログインリダイレクト
  3. 並行運用期間 — 旧ログイン(POST /login)と新ログイン(OIDC)を両方生かす。既存セッションは期限切れまで有効
  4. 旧ログイン廃止 — 全ユーザーが OIDC 経由になったことを確認して旧エンドポイントを削除
  5. 残りのプロダクトに展開 — 1で得た知見をもとに横展開

まとめ

← Back to all posts