從 edge-ai-platform POC 轉為正式產品的雲端後端,含以下整合階段:
- Phase 0:雛形骨架 — `cmd/api-server` (REST :3721) + `cmd/remote-proxy`
(tunnel :3800 / internal :3801) 雙 binary 共用 internal/,沿用 POC 的
WebSocket+yamux tunnel 協定但解耦 relay 與 API
- Phase 0.6:OIDC BFF 接 Innovedus Member Center
- internal/oidc package(coreos/go-oidc + PKCE S256 + state + nonce)
- internal/usersession package(HMAC-SHA256 cookie + RotateSessionID
防 session fixation, OWASP ASVS V3.2.1)
- 4 個 OIDC handler(/api/auth/login|callback|me|logout)+ AuthMiddleware
- 完全拔除 StaticAuthProvider,OIDC 是唯一認證路徑
- 9 個 ADR(含 ADR-010 BFF / ADR-011 取代 static auth /
ADR-012 pending session shared cookie / ADR-013 PKCE-only public client)
- Phase 0.7:A1 改造 + security audit 修復
- OIDC ClientSecret 變選填,支援 stage MC 的 public PKCE-only client
(AuthStyleInParams 強制 token endpoint 不送 client_secret)
- 預留 ServiceClient* 欄位給未來 client_credentials grant
- 移除 13+ 處 resolveUserID(uc, StaticUserID) fallback 改 strict mode
(Audit C1:multi-tenant 隔離破口)
- Pairing exchange MarkUsed 失敗 abort + revoke session token(Audit M3)
- 新增 all_endpoints_require_auth_test 整合測試(51 endpoint × 401)
驗證:go test -race -count=3 ./... 17 packages 全綠 / go vet 0 warning
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
56 lines
2.3 KiB
Go
56 lines
2.3 KiB
Go
// Package oidc 提供 OpenID Connect (Authorization Code + PKCE) client 的封裝,
|
||
// 對接 Innovedus Member Center 或任何 OIDC compliant Identity Provider。
|
||
//
|
||
// 設計對齊:
|
||
// - oidc-tdd.md §4.2(internal/oidc/ 模組)
|
||
// - oidc-tdd.md §6(PKCE 細節)
|
||
// - oidc-tdd.md §7(id_token 驗證)
|
||
// - adr-010-oidc-bff.md
|
||
//
|
||
// 此 package 僅提供「OIDC client wrapper」職責:
|
||
// - Discovery / JWKS(藉由 coreos/go-oidc/v3 實作,自動快取)
|
||
// - PKCE / state / nonce 隨機值產生
|
||
// - Authorization URL 組裝
|
||
// - Authorization Code → Token Exchange
|
||
// - id_token 驗證(簽章 + claim)
|
||
//
|
||
// 不負責:HTTP handler、cookie session、frontend redirect — 這些由 OB3-OB4 處理。
|
||
package oidc
|
||
|
||
import "errors"
|
||
|
||
// 公開 sentinel errors,便於 caller 用 errors.Is 比對。
|
||
// 命名與 internal/auth 風格一致。
|
||
var (
|
||
// ErrDiscoveryFetch 表示 .well-known/openid-configuration 抓取或解析失敗。
|
||
ErrDiscoveryFetch = errors.New("oidc: discovery fetch failed")
|
||
|
||
// ErrJWKSFetch 表示 jwks_uri 抓取或解析失敗。
|
||
ErrJWKSFetch = errors.New("oidc: jwks fetch failed")
|
||
|
||
// ErrTokenExchange 表示 token endpoint 回傳錯誤(非 401)或網路錯誤。
|
||
ErrTokenExchange = errors.New("oidc: token exchange failed")
|
||
|
||
// ErrInvalidGrant 表示 authorization code 已被使用、過期、或 PKCE verifier 不符(HTTP 400/401 with invalid_grant)。
|
||
ErrInvalidGrant = errors.New("oidc: invalid grant")
|
||
|
||
// ErrInvalidIDToken 是 id_token 驗證失敗的 umbrella error;
|
||
// 包裹下方更精確的 sentinel,caller 可用 errors.Is 逐個檢查。
|
||
ErrInvalidIDToken = errors.New("oidc: invalid id_token")
|
||
|
||
// ErrInvalidIssuer 表示 id_token 的 iss claim 不等於 cfg.IssuerURL。
|
||
ErrInvalidIssuer = errors.New("oidc: invalid issuer")
|
||
|
||
// ErrInvalidAudience 表示 id_token 的 aud claim 不包含 cfg.ClientID。
|
||
ErrInvalidAudience = errors.New("oidc: invalid audience")
|
||
|
||
// ErrTokenExpired 表示 id_token 已過期(exp <= now,含 leeway)。
|
||
ErrTokenExpired = errors.New("oidc: id_token expired")
|
||
|
||
// ErrInvalidNonce 表示 id_token 的 nonce claim 與 caller 提供的 expectedNonce 不符。
|
||
ErrInvalidNonce = errors.New("oidc: invalid nonce")
|
||
|
||
// ErrInvalidConfig 表示 ProviderConfig 缺欄位或欄位格式錯誤。
|
||
ErrInvalidConfig = errors.New("oidc: invalid config")
|
||
)
|