feat(identity): 实现统一认证运行时热切换

从 Active Revision 构造并验证 OIDC、BFF Session、Introspection 与 SSF Runtime,在数据库激活成功后原子替换内存引用。请求链路使用不可变快照,失败保留当前运行时,本地管理登录不受影响。\n\n验证:go test ./apps/api/...;go vet ./apps/api/...
This commit is contained in:
2026-07-17 12:05:00 +08:00
parent 96bbd3a2f6
commit a9e23cb237
14 changed files with 797 additions and 152 deletions
+33 -15
View File
@@ -73,16 +73,19 @@ func NewRequestAuthError(status int, code, message string) error {
}
type Authenticator struct {
JWTSecret string
ServerMainBaseURL string
ServerMainInternalToken string
ServerMainInternalKey string
ServerMainInternalSecret string
HTTPClient *http.Client
LocalAPIKeyVerifier func(ctx context.Context, apiKey string) (*User, error)
OIDCVerifier *OIDCVerifier
OIDCSessionResolver func(ctx context.Context, sessionID string) (*User, error)
LegacyJWTEnabled bool
JWTSecret string
ServerMainBaseURL string
ServerMainInternalToken string
ServerMainInternalKey string
ServerMainInternalSecret string
HTTPClient *http.Client
LocalAPIKeyVerifier func(ctx context.Context, apiKey string) (*User, error)
OIDCVerifier *OIDCVerifier
OIDCVerifierProvider func() *OIDCVerifier
OIDCSessionResolver func(ctx context.Context, sessionID string) (*User, error)
OIDCSessionResolverProvider func(ctx context.Context, sessionID string) (*User, error)
LegacyJWTEnabled bool
LegacyJWTEnabledProvider func() bool
}
func New(jwtSecret string, serverMainBaseURL string, internalToken string) *Authenticator {
@@ -152,10 +155,14 @@ func (a *Authenticator) Authenticate(r *http.Request) (*User, error) {
if token == "" {
if cookie, err := r.Cookie(OIDCSessionCookieName); err == nil {
sessionID := strings.TrimSpace(cookie.Value)
if sessionID == "" || a.OIDCSessionResolver == nil {
resolver := a.OIDCSessionResolver
if a.OIDCSessionResolverProvider != nil {
resolver = a.OIDCSessionResolverProvider
}
if sessionID == "" || resolver == nil {
return nil, ErrUnauthorized
}
return a.OIDCSessionResolver(r.Context(), sessionID)
return resolver(r.Context(), sessionID)
}
}
if token == "" {
@@ -168,7 +175,7 @@ func (a *Authenticator) Authenticate(r *http.Request) (*User, error) {
if algorithm == "RS256" || algorithm == "ES256" {
return a.AuthenticateOIDCAccessToken(r.Context(), token)
}
if !a.LegacyJWTEnabled {
if !a.legacyJWTEnabled() {
return nil, ErrUnauthorized
}
return a.verifyJWT(token)
@@ -176,10 +183,21 @@ func (a *Authenticator) Authenticate(r *http.Request) (*User, error) {
func (a *Authenticator) AuthenticateOIDCAccessToken(ctx context.Context, token string) (*User, error) {
algorithm := jwtAlgorithm(token)
if a.OIDCVerifier == nil || algorithm != "RS256" && algorithm != "ES256" {
verifier := a.OIDCVerifier
if a.OIDCVerifierProvider != nil {
verifier = a.OIDCVerifierProvider()
}
if verifier == nil || algorithm != "RS256" && algorithm != "ES256" {
return nil, ErrUnauthorized
}
return a.OIDCVerifier.Verify(ctx, token)
return verifier.Verify(ctx, token)
}
func (a *Authenticator) legacyJWTEnabled() bool {
if a.LegacyJWTEnabledProvider != nil {
return a.LegacyJWTEnabledProvider()
}
return a.LegacyJWTEnabled
}
func (a *Authenticator) verifyJWT(tokenString string) (*User, error) {