Chuyển đến nội dung chính

レッスン 16: 認証と認可 — マイクロ フロントエンドの SSO

マイクロ フロントエンドの SSO アーキテクチャ。 Keycloakの統合。 OAuth2/OIDC フロー。トークン管理。 RBAC。シェルと MFE 間のトークン共有。

🏗️ アーキテクチャ — レッスン 16 レッスン 16: 認証と認可 — マイクロフロントエンドの SSO

マイクロサービスとマイクロ フロントエンドのシステム設計 — 基本から運用まで

パート 5: 実用的なマイクロ フロントエンドの構築

xdev.asia

はじめに

マイクロ フロントエンドでの認証は通常の SPA よりも複雑です。シェル アプリがログインを処理しますが、すべての MFE にはアクセス トークンが必要です。この記事では、Keycloak を使用して SSO アーキテクチャを設計します。


1. SSO アーキテクチャ

┌──────────┐   1. Login    ┌──────────┐
│  Shell   │──────────────►│ Keycloak │
│  App     │◄──────────────│  (OIDC)  │
│          │   2. Tokens   └──────────┘
│          │
│ 3. Store tokens (memory)
│ 4. Broadcast auth state
│          │
│  ┌───────┴───────┐
│  ▼               ▼
│ MFE A          MFE B
│ (useAuth)      (useAuth)
│  │               │
│  ▼               ▼
│ API calls with Bearer token
└─────────────────────────

OIDC 認証コード フロー + PKCE

1. User clicks Login → Shell redirects to Keycloak
2. User authenticates → Keycloak redirects back with auth code
3. Shell exchanges auth code for tokens (PKCE)
4. Tokens: Access (5 min), Refresh (30 min), ID Token
5. Shell stores in memory (NOT localStorage!)
6. Shell broadcasts auth state to MFEs

2. トークン管理

2.1 ストレージのセキュリティ

❌ localStorage / sessionStorage: XSS vulnerable
✅ Memory (JS variable): Cleared on refresh + silent renew
✅ HTTP-only Cookie: For BFF pattern (server-side)

2.2 トークンの共有

// Option 1: React Context (same React via Module Federation)
<AuthContext.Provider value={auth}>
  <MFEContainer />
</AuthContext.Provider>

// Option 2: Events (framework agnostic)
window.dispatchEvent(new CustomEvent('auth:token-updated', {
  detail: { accessToken, user, roles }
}));

2.3 サイレント更新

useEffect(() => {
  const interval = setInterval(async () => {
    const newTokens = await keycloak.refresh(refreshToken);
    broadcastToken(newTokens.accessToken);
  }, 4 * 60 * 1000); // Refresh 1 min before expiry
  return () => clearInterval(interval);
}, [refreshToken]);

3. 認可 — RBAC

Keycloak Roles:
├── admin       → Full access
├── manager     → Order + Product management
├── editor      → Product editing only
├── customer    → Shopping, order history
└── guest       → Browse products only

フロントエンドの認可

// Shell: route-level guard
<Route path="/admin/*" element={
  <RequireRole role="admin"><AdminMFE /></RequireRole>
} />

// MFE: feature-level guard
{hasRole('editor') && <EditButton />}
{hasRole('admin') && <DeleteButton />}

バックエンド認証 (API ゲートウェイ)

routes:
  - path: /api/products
    methods: [POST, PUT, DELETE]
    plugins:
      jwt-auth: {}
      rbac: { required_roles: ["editor", "admin"] }

重要: フロントエンド認証は UX のみです — バックエンドは常に検証する必要があります。


4. セキュリティのベストプラクティス

練習説明
メモリ内のトークンアクセス トークンを localStorage に保存しないでください。
HTTP のみの CookieBFF パターンの場合
PKCESPAに必要
有効期間の短いトークンアクセス: 5 分、リフレッシュ: 30 分
トークンローテーション更新するたびに新しい更新トークン
CORS 厳格既知の起源のみを受け入れる
CSP ヘッダーXSS を防ぐ

概要

  • シェル独自の認証 — ログイン、ログアウト、トークン管理
  • MFE はコンテキストまたはイベント経由でトークンを受け取ります
  • メモリ内のトークン + サイレントリフレッシュ
  • RBAC: ルートレベル + 機能レベル + API レベル
  • バックエンドは常に検証します

次の記事: レッスン 17: BFF パターン — フロントエンド用のバックエンド