自定义声明(Claims Mapping)
自 v1.6.0(P1-3,#280)起,fulla 可以把按用户维护的自定义声明发布进
id_token 与 userinfo:用户在自助端维护 custom_attributes 文档,管理员把
一个来源路径映射为触发 scope 之下的已发布声明——即 Keycloak 协议映射器的
最小等价物。本页记录模型、两个 API 面、安全红线(及其 成因)、发布语义与缓存行为。
先读这段:这个特性是刻意收窄的。映射只能读
custom_attributes.<key>或内置的user.display_name,永远不能遮蔽标准声明, 且以 RP 显式请求的 scope 为门。如果你需要任意声明变换或联邦协议映射器, 那是设计上就不做的(见 §7)。
1. 模型(V044)
一条迁移交付整个特性——V044__custom_attributes_claim_mappings.sql:
-- 用户侧来源数据(自助、整体替换)
ALTER TABLE users ADD COLUMN IF NOT EXISTS custom_attributes JSONB
NOT NULL DEFAULT '{}';
CREATE INDEX idx_users_custom_attributes_gin ON users USING GIN (custom_attributes);
-- 管理侧发布规则
CREATE TABLE claim_mappings (
id SERIAL PRIMARY KEY,
scope_name VARCHAR(64) NOT NULL, -- 触发 scope(禁止 'openid')
claim_name VARCHAR(64) NOT NULL, -- 发布的声 明名
source_path VARCHAR(128) NOT NULL, -- custom_attributes.<key> | user.display_name
include_in VARCHAR(16) NOT NULL DEFAULT 'both', -- id_token | userinfo | both
enabled BOOLEAN NOT NULL DEFAULT TRUE,
CONSTRAINT uq_claim_mappings UNIQUE (scope_name, claim_name)
);
一条映射就是一条规则:当令牌/userinfo 请求携带 scope_name 时,把
source_path 处找到的值发布为 claim_name 声明,发布面由 include_in
选择。唯一约束保证每个 scope 下一个声明名只出现一次;同一声明名挂到别的
scope 是另一行。
仅限 Postgres——没有内存态 claim-mapping 存储:自助面在内存存储部署上答
404(自定义属性是 claims-mapping 的来源数据,不是资料字段);管理端 CRUD
需要数据库客户端,缺失时答 DB_CONNECTION_ERROR。