# 機能設計書 28-認証（SecurityRealm）

## 概要

本ドキュメントは、JenkinsのSecurityRealm機能の設計仕様を定義する。SecurityRealmは、外部ユーザーデータベースとJenkinsを接続し、ユーザー認証を行うためのプラグイン可能な抽象化レイヤーを提供する。

### 本機能の処理概要

SecurityRealmは、Jenkinsへのユーザーログイン時の認証処理を担う拡張ポイントである。LDAP、Active Directory、Unix PAM、Jenkins独自のユーザーデータベースなど、様々な認証バックエンドをサポートする。

**業務上の目的・背景**：エンタープライズ環境では、既存の認証基盤（Active Directory、LDAP等）との統合が必須要件となる。SecurityRealmは、Jenkinsを様々な認証システムと柔軟に連携させるための拡張ポイントを提供する。

**機能の利用シーン**：
- LDAPサーバーを使用したユーザー認証
- Active Directoryとのシングルサインオン
- GitHub/GitLab OAuthによるソーシャルログイン
- SAML 2.0によるフェデレーション認証
- Jenkins独自のユーザーデータベースによる認証

**主要な処理内容**：
1. ユーザー認証（AuthenticationManager）
2. ユーザー詳細情報の取得（UserDetailsService）
3. 認証フィルターチェーンの構築（createFilter）
4. ログイン/ログアウト処理
5. Remember-Me機能の提供
6. グループ情報の取得（loadGroupByGroupname）

**関連システム・外部連携**：LDAP、Active Directory、OAuth providers、SAML IdP、Spring Security、Servlet Filter。

**権限による制御**：SecurityRealmの設定はAdminister権限を持つユーザーのみが変更可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | ログイン | 主画面 | ユーザー認証処理 |
| 8 | セキュリティ設定 | 設定画面 | SecurityRealmの選択・設定 |

## 機能種別

拡張ポイント / セキュリティ・認証

## 入力仕様

### 入力パラメータ（認証処理）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| username | String | Yes | ユーザー名 | 空文字不可 |
| password | String | Yes | パスワード | 空文字不可 |
| remember_me | boolean | No | Remember-Meフラグ | true/false |

### 入力データソース

ログインフォームからの入力、Basic認証ヘッダー、API Token。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Authentication | Authentication | 認証済みユーザー情報 |
| SecurityContext | SecurityContext | セキュリティコンテキスト |
| Session | HttpSession | 認証済みセッション |

### 出力先

- HTTPセッション
- SecurityContextHolder
- Remember-Me Cookie

## 処理フロー

### 処理シーケンス

```
1. ログインリクエスト受信
   └─ j_spring_security_checkへのPOST
2. AuthenticationProcessingFilter2で認証処理
   └─ AuthenticationManager.authenticate()呼び出し
3. SecurityRealm固有の認証ロジック実行
   └─ 外部認証システムへの問い合わせ
4. 認証成功時
   └─ Authenticationオブジェクト生成
   └─ SecurityContextに設定
   └─ SessionFixationProtection適用
5. Remember-Me処理（オプション）
   └─ TokenBasedRememberMeServices2でCookie設定
6. 成功ページへリダイレクト
```

### フローチャート

```mermaid
flowchart TD
    A[ログインリクエスト] --> B[AuthenticationProcessingFilter2]
    B --> C[AuthenticationManager.authenticate]
    C --> D{認証成功?}
    D -->|Yes| E[Authentication生成]
    D -->|No| F[認証失敗ページ]
    E --> G[SecurityContext設定]
    G --> H{Remember-Me?}
    H -->|Yes| I[Cookie設定]
    H -->|No| J[成功ページリダイレクト]
    I --> J
    F --> K[ログインページ再表示]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | セッション固定保護 | 認証成功時にセッションIDを再生成 | 全認証 |
| BR-002 | Remember-Me期間 | TokenBasedRememberMeServices2で管理 | Remember-Me有効時 |
| BR-003 | 認証済み権限 | authenticatedグループが自動付与 | 認証成功時 |
| BR-004 | ログアウト時のセッション無効化 | セッションを破棄してCookieをクリア | ログアウト時 |

### 計算ロジック

```java
// 認証済み権限の自動付与
public static final GrantedAuthority AUTHENTICATED_AUTHORITY2 =
    new SimpleGrantedAuthority("authenticated");
```

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 設定保存 | config.xml | INSERT/UPDATE | SecurityRealm設定の永続化 |

### テーブル別操作詳細

#### config.xml（Jenkins設定ファイル）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT/UPDATE | securityRealm | SecurityRealm設定 | XMLシリアライズ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | UsernameNotFoundException | ユーザーが存在しない | ログインエラーページ表示 |
| - | AuthenticationException | 認証失敗（パスワード不一致等） | ログインエラーページ表示 |
| - | UserMayOrMayNotExistException2 | ユーザー存在判定不可 | 最小権限でのアクセス許可 |

### リトライ仕様

認証リトライは行わない。ユーザーは再度ログインフォームから認証を試行。

## トランザクション仕様

認証処理自体にトランザクション管理はない。外部認証システムへの問い合わせは同期的に実行。

## パフォーマンス要件

- 認証処理は数秒以内に完了することが期待される
- LDAP/AD認証では接続プールの使用を推奨

## セキュリティ考慮事項

- パスワードはログに出力しない
- セッション固定攻撃への対策（SessionFixationProtectionStrategy）
- CSRF対策が適用される
- Remember-Me Cookieはセキュア属性付きで設定

## 備考

- NO_AUTHENTICATIONは認証なしモードのシングルトン
- HudsonPrivateSecurityRealmはJenkins独自のユーザーデータベース実装
- Spring Securityのフィルターチェーンを使用

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

SecurityRealmの基本構造とSecurityComponentsを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SecurityRealm.java | `core/src/main/java/hudson/security/SecurityRealm.java` | 抽象クラス定義、SecurityComponents内部クラス |

**読解のコツ**: SecurityRealmは抽象クラスで、createSecurityComponents()が主要な抽象メソッド。SecurityComponentsはAuthenticationManager、UserDetailsService、RememberMeServicesをまとめて保持。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | SecurityRealm.java | `core/src/main/java/hudson/security/SecurityRealm.java` | createSecurityComponents()、getSecurityComponents() |

**主要処理フロー**:
- **151行目**: SecurityRealm - クラス定義（Describable, ExtensionPoint実装）
- **173行目**: createSecurityComponents() - 抽象メソッド、認証コンポーネント生成
- **604-609行目**: getSecurityComponents() - SecurityComponentsのシングルトン取得

#### Step 3: フィルターチェーンを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SecurityRealm.java | `core/src/main/java/hudson/security/SecurityRealm.java` | createFilter()、createFilterImpl() |

**主要処理フロー**:
- **626-633行目**: createFilter() - フィルターチェーン生成
- **645-684行目**: createFilterImpl() - デフォルトフィルターチェーン構築
- **686-694行目**: commonFilters() - 共通フィルター（Anonymous、ExceptionTranslation等）

#### Step 4: ログイン/ログアウトを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | SecurityRealm.java | `core/src/main/java/hudson/security/SecurityRealm.java` | doLogout()、getLoginUrl()、getPostLogOutUrl2() |

**主要処理フロー**:
- **248-250行目**: getLoginUrl() - ログインページURL
- **285-312行目**: getPostLogOutUrl2() - ログアウト後のリダイレクト先
- **346-384行目**: doLogout() - ログアウト処理

### プログラム呼び出し階層図

```
ログインリクエスト
    │
    └─ ChainedServletFilter2
           │
           ├─ HttpSessionSecurityContextFilter
           │      └─ セッションからSecurityContext復元
           │
           ├─ BasicHeaderProcessor
           │      └─ Basic認証処理
           │
           ├─ AuthenticationProcessingFilter2
           │      │
           │      ├─ SecurityRealm.getSecurityComponents()
           │      │      └─ SecurityComponents取得
           │      │
           │      └─ AuthenticationManager.authenticate()
           │             └─ [実装依存] 認証処理
           │
           ├─ RememberMeAuthenticationFilter
           │      └─ Remember-Me Cookie処理
           │
           └─ AnonymousAuthenticationFilter
                  └─ 匿名ユーザー処理

SecurityRealm.doLogout()
    │
    ├─ session.invalidate()
    │      └─ セッション無効化
    │
    ├─ SecurityContextHolder.clearContext()
    │      └─ コンテキストクリア
    │
    ├─ resetRememberMeCookie()
    │      └─ Cookie削除
    │
    └─ rsp.sendRedirect2(getPostLogOutUrl2())
           └─ リダイレクト
```

### データフロー図

```
[入力]                    [処理]                         [出力]

ユーザー名/パスワード   SecurityRealm
├─ ログインフォーム   ├─ AuthenticationManager ───▶   Authentication
├─ Basic認証ヘッダー  │      .authenticate()
└─ API Token         │
                     ├─ UserDetailsService ──────▶   UserDetails
                     │      .loadUserByUsername()
                     │
                     └─ RememberMeServices ──────▶   Remember-Me Cookie

SecurityComponents    SecurityRealm
├─ manager2         ├─ createFilter() ───────────▶   Filter Chain
├─ userDetails2     │
└─ rememberMe2      └─ createSecurityComponents() ─▶ SecurityComponents
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| SecurityRealm.java | `core/src/main/java/hudson/security/SecurityRealm.java` | ソース | セキュリティレルム抽象基底クラス |
| HudsonPrivateSecurityRealm.java | `core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java` | ソース | Jenkins独自ユーザーDB実装 |
| LegacySecurityRealm.java | `core/src/main/java/hudson/security/LegacySecurityRealm.java` | ソース | レガシーコンテナ認証 |
| AuthenticationProcessingFilter2.java | `core/src/main/java/hudson/security/AuthenticationProcessingFilter2.java` | ソース | 認証処理フィルター |
| TokenBasedRememberMeServices2.java | `core/src/main/java/hudson/security/TokenBasedRememberMeServices2.java` | ソース | Remember-Meサービス |
| ChainedServletFilter2.java | `core/src/main/java/hudson/security/ChainedServletFilter2.java` | ソース | フィルターチェーン |
| GroupDetails.java | `core/src/main/java/hudson/security/GroupDetails.java` | ソース | グループ詳細情報 |
