feat(identity): 接入认证中心多租户登录

支持 Manifest V2 动态 tid 验证、Tenant Context 同步和租户内 JIT 投影,并保留 Manifest V1 与旧 Session 兼容。\n\n增加 tenantHint、租户切换、普通注册关闭及 application/principal/tenant 两级 SSF 撤销;迁移、定向安全测试和本地双租户跨仓 E2E 已通过。\n\nrelease_required=true;未执行 Release、Staging 或真实链路。
This commit is contained in:
2026-07-28 17:28:35 +08:00
parent 0b02e62c72
commit 5c679ff13f
45 changed files with 2986 additions and 139 deletions
@@ -7,6 +7,8 @@ import (
"net/url"
"strings"
"time"
"github.com/google/uuid"
)
const LoginTransactionCookieName = "easyai_gateway_oidc_login"
@@ -18,10 +20,15 @@ type LoginTransaction struct {
Nonce string `json:"nonce"`
PKCEVerifier string `json:"pkceVerifier"`
ReturnTo string `json:"returnTo"`
TenantHint string `json:"tenantHint,omitempty"`
CreatedAt time.Time `json:"createdAt"`
}
func NewLoginTransaction(returnTo string, now time.Time) (LoginTransaction, error) {
return NewLoginTransactionWithTenantHint(returnTo, "", now)
}
func NewLoginTransactionWithTenantHint(returnTo, tenantHint string, now time.Time) (LoginTransaction, error) {
if !ValidReturnTo(returnTo) {
return LoginTransaction{}, errors.New("returnTo must be a same-origin relative path")
}
@@ -37,7 +44,10 @@ func NewLoginTransaction(returnTo string, now time.Time) (LoginTransaction, erro
if err != nil {
return LoginTransaction{}, err
}
return LoginTransaction{State: state, Nonce: nonce, PKCEVerifier: verifier, ReturnTo: returnTo, CreatedAt: now.UTC()}, nil
return LoginTransaction{
State: state, Nonce: nonce, PKCEVerifier: verifier,
ReturnTo: returnTo, TenantHint: strings.TrimSpace(tenantHint), CreatedAt: now.UTC(),
}, nil
}
func (c *Cipher) EncodeLoginTransaction(transaction LoginTransaction) (string, error) {
@@ -58,6 +68,7 @@ func (c *Cipher) DecodeLoginTransaction(encoded string, now time.Time) (LoginTra
return LoginTransaction{}, err
}
if transaction.State == "" || transaction.Nonce == "" || transaction.PKCEVerifier == "" || !ValidReturnTo(transaction.ReturnTo) ||
transaction.TenantHint != "" && uuid.Validate(transaction.TenantHint) != nil ||
transaction.CreatedAt.IsZero() || now.Before(transaction.CreatedAt.Add(-time.Minute)) || !now.Before(transaction.CreatedAt.Add(10*time.Minute)) {
return LoginTransaction{}, errors.New("OIDC login transaction has expired or is invalid")
}