Major Features: - ✅ Multi-tenant architecture (tenant isolation) - ✅ Employee CRUD with lifecycle management (onboarding/offboarding) - ✅ Department tree structure with email domain management - ✅ Company info management (single-record editing) - ✅ System functions CRUD (permission management) - ✅ Email account management (multi-account per employee) - ✅ Keycloak SSO integration (auth.lab.taipei) - ✅ Redis session storage (10.1.0.254:6379) - Solves Cookie 4KB limitation - Cross-system session sharing - Sliding expiration (8 hours) - Automatic token refresh Technical Stack: Backend: - FastAPI + SQLAlchemy - PostgreSQL 16 (10.1.0.20:5433) - Keycloak Admin API integration - Docker Mailserver integration (SSH) - Alembic migrations Frontend: - Next.js 14 (App Router) - NextAuth 4 with Keycloak Provider - Redis session storage (ioredis) - Tailwind CSS Infrastructure: - Redis 7 (10.1.0.254:6379) - Session + Cache - Keycloak 26.1.0 (auth.lab.taipei) - Docker Mailserver (10.1.0.254) Architecture Highlights: - Session管理由 Keycloak + Redis 統一控制 - 支援多系統 (HR/WebMail/Calendar/Drive/Office) 共享 session - Token 自動刷新,異質服務整合 - 未來可無縫遷移到雲端 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
216 lines
5.4 KiB
Markdown
216 lines
5.4 KiB
Markdown
# Keycloak Client 設定檢查清單
|
|
|
|
## Client: hr-portal-web
|
|
|
|
### ✅ Access Settings (已完成)
|
|
- [x] Valid redirect URIs: 已設定三個環境
|
|
- [x] Valid post logout redirect URIs: 已設定
|
|
- [x] Web origins: 已設定 CORS
|
|
|
|
### ⏳ General Settings (需確認)
|
|
|
|
請確認以下設定:
|
|
|
|
#### Client ID
|
|
```
|
|
hr-portal-web
|
|
```
|
|
|
|
#### Client Protocol
|
|
```
|
|
openid-connect
|
|
```
|
|
|
|
#### Access Type
|
|
```
|
|
public ← 必須是 public,因為是 SPA 應用
|
|
```
|
|
|
|
#### Standard Flow Enabled
|
|
```
|
|
ON ← 必須開啟
|
|
```
|
|
|
|
#### Direct Access Grants Enabled
|
|
```
|
|
OFF ← 建議關閉 (SPA 不需要)
|
|
```
|
|
|
|
#### Implicit Flow Enabled
|
|
```
|
|
OFF ← 必須關閉 (使用 Standard Flow + PKCE)
|
|
```
|
|
|
|
### ⏳ Advanced Settings (需確認)
|
|
|
|
#### Proof Key for Code Exchange Code Challenge Method
|
|
```
|
|
S256 ← 必須設定為 S256
|
|
```
|
|
|
|
這個設定非常重要!必須啟用 PKCE 以確保安全性。
|
|
|
|
位置:
|
|
1. 進入 Client 詳細頁面
|
|
2. 切換到 **Advanced Settings** 標籤
|
|
3. 找到 **Proof Key for Code Exchange Code Challenge Method**
|
|
4. 選擇 **S256**
|
|
5. 點擊 **Save**
|
|
|
|
### ⏳ Client Scopes (需確認)
|
|
|
|
確認以下 scopes 在 **Assigned Default Client Scopes**:
|
|
|
|
#### 必須有的 Scopes
|
|
- [x] `openid` - OpenID Connect 核心
|
|
- [x] `profile` - 使用者基本資料 (name, username)
|
|
- [x] `email` - 使用者電子郵件
|
|
|
|
#### 檢查方式
|
|
1. 進入 Client 詳細頁面
|
|
2. 切換到 **Client Scopes** 標籤
|
|
3. 查看 **Assigned Default Client Scopes** 區塊
|
|
4. 確認 `openid`, `profile`, `email` 都在列表中
|
|
5. 如果沒有,從 **Available Client Scopes** 加入
|
|
|
|
### ⏳ Roles (選用,但建議設定)
|
|
|
|
為了權限控制,建議在 Realm 中建立以下 Roles:
|
|
|
|
#### 進入 Realm Roles
|
|
1. 左側選單選擇 **Realm Roles**
|
|
2. 點擊 **Add Role**
|
|
|
|
#### 建議的 Roles
|
|
```
|
|
hr-admin - HR 管理員 (完整權限)
|
|
hr-manager - HR 經理 (查看與編輯)
|
|
hr-viewer - HR 檢視者 (僅查看)
|
|
```
|
|
|
|
#### 設定步驟 (每個 Role)
|
|
1. Role Name: 輸入 `hr-admin` (或其他)
|
|
2. Description: 輸入說明,例如 "HR Portal Administrator"
|
|
3. 點擊 **Save**
|
|
|
|
### ⏳ 使用者設定 (測試用)
|
|
|
|
為測試帳號指派 Role:
|
|
|
|
1. 左側選單選擇 **Users**
|
|
2. 找到你的測試帳號 (例如: porsche)
|
|
3. 點擊進入使用者詳細頁面
|
|
4. 切換到 **Role Mappings** 標籤
|
|
5. 在 **Available Roles** 中找到 `hr-admin`
|
|
6. 點擊 **Add selected** 將 role 加入
|
|
7. 確認 role 出現在 **Assigned Roles** 中
|
|
|
|
## 測試流程
|
|
|
|
### 1. 檢查 OIDC Discovery Endpoint
|
|
|
|
在瀏覽器或使用 curl 訪問:
|
|
```
|
|
https://auth.ease.taipei/realms/porscheworld/.well-known/openid-configuration
|
|
```
|
|
|
|
應該能看到完整的 OpenID Connect 配置。
|
|
|
|
### 2. 測試前端登入
|
|
|
|
#### 步驟:
|
|
1. 確認開發伺服器運行: `npm run dev`
|
|
2. 瀏覽器開啟: `http://localhost:3000`
|
|
3. 應該會看到登入頁面
|
|
4. 點擊「使用 SSO 登入」
|
|
5. 應該會跳轉到 Keycloak 登入頁面
|
|
6. 輸入帳號密碼登入
|
|
7. 登入成功後應該回到 HR Portal 首頁
|
|
8. Header 應該顯示使用者名稱和 Email
|
|
|
|
#### 預期結果:
|
|
- ✅ 成功跳轉到 Keycloak
|
|
- ✅ 登入成功回到應用
|
|
- ✅ Header 顯示正確的使用者資訊
|
|
- ✅ 可以正常瀏覽各個頁面
|
|
- ✅ 登出功能正常
|
|
|
|
#### 如果失敗:
|
|
1. 開啟瀏覽器開發者工具 (F12)
|
|
2. 查看 Console 是否有錯誤訊息
|
|
3. 查看 Network 標籤,檢查 Keycloak 的請求
|
|
4. 常見錯誤:
|
|
- **Invalid redirect_uri**: 檢查 Valid Redirect URIs 設定
|
|
- **CORS error**: 檢查 Web Origins 設定
|
|
- **Invalid client**: 檢查 Client ID 是否正確
|
|
- **PKCE required**: 檢查 PKCE 是否設定為 S256
|
|
|
|
### 3. 測試 Token 刷新
|
|
|
|
登入後:
|
|
1. 保持應用開啟
|
|
2. 觀察 Console (每 30 秒會檢查 Token)
|
|
3. 應該會看到 "Token 已刷新" 訊息 (如果 Token 快過期)
|
|
|
|
### 4. 測試 API 呼叫
|
|
|
|
登入後:
|
|
1. 訪問員工列表頁面: `http://localhost:3000/employees`
|
|
2. 開啟開發者工具 Network 標籤
|
|
3. 檢查 API 請求 (例如: GET /api/v1/employees)
|
|
4. 查看 Request Headers
|
|
5. 應該包含: `Authorization: Bearer eyJhbG...` (Token)
|
|
|
|
## 完成確認
|
|
|
|
全部完成後,請確認:
|
|
|
|
- [ ] Client ID 為 `hr-portal-web`
|
|
- [ ] Access Type 為 `public`
|
|
- [ ] Standard Flow 已啟用
|
|
- [ ] PKCE 設定為 S256
|
|
- [ ] Valid Redirect URIs 已正確設定
|
|
- [ ] Web Origins 已正確設定
|
|
- [ ] Client Scopes 包含 openid, profile, email
|
|
- [ ] 測試帳號已指派 hr-admin role
|
|
- [ ] 前端登入測試成功
|
|
- [ ] Token 自動刷新運作正常
|
|
- [ ] API 請求自動帶入 Bearer Token
|
|
|
|
## 疑難排解
|
|
|
|
### 問題: Invalid redirect_uri
|
|
**原因**: Valid Redirect URIs 設定錯誤
|
|
**解決**: 確認 URIs 完全匹配,包含 protocol (http/https)、host、port
|
|
|
|
### 問題: CORS error
|
|
**原因**: Web Origins 未設定
|
|
**解決**: 在 Web Origins 加入應用的 origin
|
|
|
|
### 問題: Token 無法刷新
|
|
**原因**: Realm 的 Token Lifespan 設定太短
|
|
**解決**:
|
|
1. Realm Settings → Tokens
|
|
2. 調整 Access Token Lifespan (建議 5-30 分鐘)
|
|
3. 調整 SSO Session Idle (建議 30 分鐘)
|
|
4. 調整 SSO Session Max (建議 10 小時)
|
|
|
|
### 問題: 使用者資訊不完整
|
|
**原因**: Client Scopes 缺少 profile 或 email
|
|
**解決**: 在 Client Scopes 加入對應的 scope
|
|
|
|
### 問題: 角色資訊取不到
|
|
**原因**: Token 中沒有包含 roles
|
|
**解決**:
|
|
1. Client Scopes → Create new scope: `roles`
|
|
2. Mappers → Create Protocol Mapper
|
|
3. Mapper Type: User Realm Role
|
|
4. Token Claim Name: realm_access.roles
|
|
5. 將 scope 加入 Client 的 Default Client Scopes
|
|
|
|
---
|
|
|
|
**文件版本**: 1.0
|
|
**最後更新**: 2026-02-09
|
|
**狀態**: 待驗證
|