feat(identity): 收敛 AI Gateway 统一认证入口

Web 登录页合并为单一统一认证入口,未指定上下文时由认证中心在登录后决策。继续接受旧客户端显式传入 platform 或 tenant,并保持回调上下文及 tenant_hint 的绑定校验。同步更新 OpenAPI 产物。\n\n验证:Go 全量测试与 go vet 通过;Web lint、141 项 Vitest 和生产构建通过;本地 platform.admin 登录及管理工作台访问通过。
This commit is contained in:
2026-07-31 15:28:12 +08:00
parent c0296dbf06
commit 59f0817938
13 changed files with 186 additions and 69 deletions
@@ -92,6 +92,43 @@ func TestOIDCPublicClientUsesAuthorizationCodePKCES256WithoutSecret(t *testing.T
}
}
func TestOIDCPublicClientOmitsOptionalContextForUnifiedLogin(t *testing.T) {
var issuer string
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/.well-known/openid-configuration" {
http.NotFound(w, r)
return
}
_ = json.NewEncoder(w).Encode(map[string]string{
"issuer": issuer, "authorization_endpoint": issuer + "/authorize",
"token_endpoint": issuer + "/token", "jwks_uri": issuer + "/jwks",
})
}))
defer server.Close()
issuer = server.URL
client, err := NewOIDCPublicClient(OIDCPublicClientConfig{
AppEnv: "test", Issuer: issuer, ClientID: "gateway-public",
RedirectURI: "https://gateway.example.com/callback",
PostLogoutRedirectURI: "https://gateway.example.com/",
HTTPClient: server.Client(),
})
if err != nil {
t.Fatal(err)
}
authorizationURL, err := client.AuthorizationURL(
context.Background(), "state", "nonce",
"test-pkce-verifier-with-at-least-43-characters-1234", "", "",
)
if err != nil {
t.Fatal(err)
}
parsed, _ := url.Parse(authorizationURL)
if parsed.Query().Has("context_type") || parsed.Query().Has("tenant_hint") {
t.Fatalf("unified login leaked optional context binding: %v", parsed.Query())
}
}
func TestOIDCPublicClientRejectsOfflineAccess(t *testing.T) {
_, err := NewOIDCPublicClient(OIDCPublicClientConfig{
AppEnv: "production",