跳到內容

03|建立 Keycloak SSO

讓瀏覽器登入後,後端拿到可驗證的身分;測試未登入、錯誤 Token 與角色不符。登入成功不代表可讀所有資料。

準備章已建立 .env 與秘密檔。確認 ORIGIN 是自己的 HTTPS 網址,再執行:

終端機視窗
python3 scripts/prepare_sso.py
python3 scripts/prepare_openbao.py
docker compose up -d --build gateway
docker compose ps
python3 scripts/configure_sso.py
python3 scripts/configure_grafana.py

gateway 會依 Compose 相依關係啟動 PostgreSQL、Keycloak 的獨立 DB、Keycloak、SSO、Grafana 與 pgAdmin。此時 OpenBao 尚未啟動,因此不要按短效憑證實驗。

Keycloak 初次啟動需要等待 healthcheck 通過。configure_sso.py 維護必要 client scope;它不會重建 realm 或重設帳號。四個示範帳密在本機 private/SSO-ACCESS.md,不要貼到共享文件。

在自己的 Tailscale 主機上配置(既有講師環境已完成,不要重複修改):

終端機視窗
tailscale serve --bg --https=28100 --set-path=/textile http://127.0.0.1:28400/textile

這是私有 Serve,不是 Funnel。其他服務也使用 28100 時,不要停用整個 port。

到 Keycloak 管理頁選 textile realm:

設定 本版值 為什麼
Web client textile-portal 登入實驗工作台
Grafana client textile-grafana 儀表板 SSO
流程 Authorization Code + PKCE S256 把登入回呼綁到原始流程
API audience textile-api 不接受發給其他服務的 Token
必要 scope basic、profile、roles 等 basic 提供 subject
Access token 5 分鐘 限制有效期

後端驗證簽章、issuer、audience、期限、subject、Token 類型與 authorized party。自行加 X-User: teacher 不會變成講師。

  1. 未登入開 /textile/sso/api/me,應 401。
  2. 開實驗工作台,用 sales.a 登入,檢查 username/department/roles。
  3. 按「測試講師限定端點」:業務應 403。
  4. 登出,再用 teacher 登入:同一端點應 200。
  5. 以 SSO 進 Grafana,確認是 Viewer;不會因此成為管理員。
  6. 先登出 Grafana,再登出實驗工作台;api/me 應回 401。
終端機視窗
docker compose exec -T sso python - < scripts/verify_sso.py

預期 18 項檢查通過。這套測試用測試簽章金鑰驗證拒絕邏輯;真正的 Keycloak 登入仍需做上面的瀏覽器驗收。

Token 留在單一後端程序記憶體;瀏覽器拿的是 Secure/HttpOnly/SameSite=Lax 不透明 cookie。工作階段最長五分鐘,重啟 SSO 會清除。Grafana 有自己的 session,目前未實作跨應用 back-channel logout。

離線 JWT 驗證不代表登出後所有既發 Token 立即作廢;沒有逐次 introspection。尚未強制 MFA,也未接 AD/LDAP。

原始碼:scripts/prepare_sso.py、scripts/configure_sso.py、sso/app.py、keycloak/start.sh。