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:
@@ -0,0 +1,92 @@
|
||||
ALTER TABLE gateway_identity_configuration_revisions
|
||||
DROP CONSTRAINT IF EXISTS gateway_identity_configuration_revisions_schema_version_check;
|
||||
|
||||
ALTER TABLE gateway_identity_configuration_revisions
|
||||
ADD COLUMN IF NOT EXISTS tenant_mode text NOT NULL DEFAULT 'single_tenant',
|
||||
ADD COLUMN IF NOT EXISTS tenant_context_endpoint text,
|
||||
ADD COLUMN IF NOT EXISTS tenant_context_audience text,
|
||||
ADD COLUMN IF NOT EXISTS tenant_context_scope text,
|
||||
ADD CONSTRAINT gateway_identity_configuration_revisions_schema_version_check
|
||||
CHECK (schema_version IN (1,2)),
|
||||
ADD CONSTRAINT gateway_identity_configuration_revisions_tenant_mode_check
|
||||
CHECK (tenant_mode IN ('single_tenant','multi_tenant')),
|
||||
ADD CONSTRAINT gateway_identity_configuration_revisions_manifest_mode_check
|
||||
CHECK (
|
||||
(state='draft' AND issuer IS NULL)
|
||||
OR
|
||||
(schema_version=1 AND tenant_mode='single_tenant' AND tenant_id IS NOT NULL AND local_tenant_key <> ''
|
||||
AND tenant_context_endpoint IS NULL AND tenant_context_audience IS NULL AND tenant_context_scope IS NULL)
|
||||
OR
|
||||
(schema_version=2 AND tenant_mode='multi_tenant' AND tenant_id IS NULL AND local_tenant_key=''
|
||||
AND tenant_context_endpoint IS NOT NULL AND tenant_context_audience='urn:easyai:auth-center:tenant-context'
|
||||
AND tenant_context_scope='tenant.context.read')
|
||||
) NOT VALID;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS gateway_oidc_tenant_bindings (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
issuer text NOT NULL,
|
||||
application_id text NOT NULL,
|
||||
external_tenant_id text NOT NULL,
|
||||
gateway_tenant_id uuid NOT NULL REFERENCES gateway_tenants(id) ON DELETE CASCADE,
|
||||
access_status text NOT NULL DEFAULT 'active'
|
||||
CHECK (access_status IN ('active','disabled')),
|
||||
metadata_status text NOT NULL DEFAULT 'metadata_pending'
|
||||
CHECK (metadata_status IN ('metadata_pending','synced','rejected')),
|
||||
display_name text,
|
||||
slug text,
|
||||
metadata_version text,
|
||||
metadata_etag text,
|
||||
metadata_updated_at timestamptz,
|
||||
last_sync_at timestamptz,
|
||||
next_sync_at timestamptz NOT NULL DEFAULT now(),
|
||||
sync_failure_count integer NOT NULL DEFAULT 0 CHECK (sync_failure_count >= 0),
|
||||
last_error_category text,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE(issuer,application_id,external_tenant_id),
|
||||
UNIQUE(id,gateway_tenant_id)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_gateway_oidc_tenant_bindings_sync
|
||||
ON gateway_oidc_tenant_bindings(next_sync_at)
|
||||
WHERE access_status='active';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS gateway_oidc_user_bindings (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_binding_id uuid NOT NULL REFERENCES gateway_oidc_tenant_bindings(id) ON DELETE CASCADE,
|
||||
subject text NOT NULL,
|
||||
gateway_user_id uuid NOT NULL REFERENCES gateway_users(id) ON DELETE CASCADE,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE(tenant_binding_id,subject),
|
||||
UNIQUE(id,gateway_user_id)
|
||||
);
|
||||
|
||||
ALTER TABLE gateway_oidc_sessions
|
||||
ADD COLUMN IF NOT EXISTS oidc_user_binding_id uuid
|
||||
REFERENCES gateway_oidc_user_bindings(id) ON DELETE CASCADE,
|
||||
ADD COLUMN IF NOT EXISTS oidc_client_id text;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_gateway_oidc_sessions_user_binding
|
||||
ON gateway_oidc_sessions(oidc_user_binding_id,created_at DESC)
|
||||
WHERE oidc_user_binding_id IS NOT NULL;
|
||||
|
||||
ALTER TABLE gateway_security_event_receipts
|
||||
ADD COLUMN IF NOT EXISTS application_id text,
|
||||
ADD COLUMN IF NOT EXISTS subject_type text
|
||||
CHECK (subject_type IS NULL OR subject_type IN ('principal','tenant'));
|
||||
|
||||
ALTER TABLE gateway_oidc_revocation_watermarks
|
||||
ADD COLUMN IF NOT EXISTS application_id text NOT NULL DEFAULT '',
|
||||
ADD COLUMN IF NOT EXISTS subject_type text NOT NULL DEFAULT 'principal'
|
||||
CHECK (subject_type IN ('principal','tenant'));
|
||||
|
||||
ALTER TABLE gateway_oidc_revocation_watermarks
|
||||
DROP CONSTRAINT IF EXISTS gateway_oidc_revocation_watermarks_pkey;
|
||||
|
||||
ALTER TABLE gateway_oidc_revocation_watermarks
|
||||
ADD PRIMARY KEY (issuer,application_id,tenant_id,subject_type,subject);
|
||||
|
||||
DROP INDEX IF EXISTS idx_gateway_oidc_revocation_watermarks_lookup;
|
||||
CREATE INDEX idx_gateway_oidc_revocation_watermarks_lookup
|
||||
ON gateway_oidc_revocation_watermarks(issuer,application_id,tenant_id,subject_type,subject,revoked_at);
|
||||
Reference in New Issue
Block a user