文章目录
keycloak配置选项之Unmanaged Attributes(未管理属性)
Keycloak 的设计逻辑
Keycloak 默认只管理 基础用户属性(如 username、email、firstName 等)。
自定义属性需要明确赋值,否则系统会视为“不存在”。
在 Keycloak 中,Unmanaged Attributes(未管理属性)是一个高级配置选项,主要用于控制 Keycloak 如何处理那些不由其直接管理的用户属性(例如来自外部用户存储的属性)。
打开这个功能,在Users下就会展示attribute标签页,暂时你自定义的用户属性。关闭这个Users菜单下,attribute标签页也就是消息。
通过打开这个,我们可以通过 Protocol Mapper 将这些属性映射到令牌(如 Access Token)中。
通过 Protocol Mapper 将用户属性映射到令牌(如 Access Token)中
Protocol Mapper 的工作机制
Protocol Mapper 仅负责将 已存在的用户属性 映射到令牌声明。
比如,我们要记录一个 last-login 这样一个用户属性,用于记录用户最后一次登录时间,
(1) 创建或更新用户属性
keycloak 默认不会自动跟踪这类信息,需通过以下方式实现:
-
手动添加(临时测试用)。
进入 Users > 目标用户 > Attributes。 -
通过 Admin REST API 批量更新
用脚本定期更新所有用户的最后登录时间:
curl -X PUT -H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"attributes": {"last-login": ["1690000000000"]}}' \
http://localhost:8080/admin/realms/your-realm/users/user-id
-
事件监听器(如 EventListenerProvider 在登录时更新属性)。
通过事件监听器(推荐)
创建一个 Keycloak 插件(SPI),在用户登录时自动更新属性。 -
自定义登录流程(通过 Required Action 或脚本触发)。
使用登录流程钩子
在 Keycloak 的 Authentication Flow 中添加一个 Execution:
进入 Authentication > Flows > 复制默认流(如 browser)。
添加一个 Script-Based Authentication 执行器,在登录成功后更新属性。
(2)创建 Protocol Mapper
进入客户端详情 → Client Scopes → 选择新建 Scope → Mappers 标签 → 点击 Create。
选择正确的 Mapper 类型
目标:将用户属性 last-login 映射到令牌声明(如 last_login)。
正确选择:User Attribute
描述:Map a custom user attribute to a token claim.
原因:last-login 是自定义属性,而非内置属性(如 email)或角色。
常见错误:
误选 User Property(仅映射内置属性如 firstName)。
误选 User Client Role(映射角色而非属性)。
字段 | 填写内容 | 说明 |
---|---|---|
Mapper type | User Attribute | 选择从用户属性映射到令牌。 |
Name* | last-login-mapper | 映射器名称(必填,建议明确用途,如 last-login-mapper )。 |
User Attribute | last-login | 用户属性名(需与用户属性表中的字段完全一致)。 |
Token Claim Name | last_login | 令牌中的声明名(建议下划线命名,如 last_login )。 |
Claim JSON Type | String | 声明值类型(时间戳推荐 String ,如 "2023-10-01T12:00:00Z" )。 |
选项 | 建议值 | 说明 |
---|---|---|
Add to ID token | On | 在 ID Token 中包含声明(适用于前端获取用户信息)。 |
Add to access token | On | 在 Access Token 中包含声明(适用于后端 API 验证)。 |
Add to lightweight access token | Off | 轻量级令牌通常不需要,除非有特殊需求。 |
Add to userinfo | On | 在 /userinfo 端点返回声明(便于查询用户信息)。 |
Add to token introspection | On | 在令牌自省(OAuth2 Introspection)响应中包含声明。 |
Multivalued | Off | last-login 是单值属性,无需启用。 |
Aggregate attribute | Off | 不涉及属性聚合(如合并 first_name 和 last_name )。 |
总结
Protocol Mapper 仅负责映射,不生成属性。
自动更新 需结合事件监听或 API 调用
(3)验证结果
(1) 获取令牌
使用密码模式获取 Access Token:
curl -X POST \
-d "client_id=my-client" \
-d "client_secret=<client-secret>" \
-d "username=user1" \
-d "password=123456" \
-d "grant_type=password" \
http://keycloak:8080/realms/my-realm/protocol/openid-connect/token
(2) 解码令牌
使用 jwt.io 解码 Access Token,检查是否包含:
{
"last_login": "2023-10-01T12:00:00Z",
"other_claims": "..."
}
(3) 通过 /userinfo 验证
curl -X GET \
-H "Authorization: Bearer <access_token>" \
http://keycloak:8080/realms/my-realm/protocol/openid-connect/userinfo
如何查看或设置用户属性?
-
通过 Keycloak Admin Console:
登录到 Keycloak 管理控制台。
导航到 Users > 选择目标用户 > 切换到 Attributes 标签页。
在这里可以添加、编辑或删除用户属性。 -
通过 REST API:
使用 Keycloak 的 REST API 可以获取或设置用户属性。例如:
GET /admin/realms/{realm}/users/{userId}
返回的 JSON 数据中会包含 attributes 字段。
示例
以下是一个用户属性的 JSON 表示:
{
"id": "123",
"username": "user1",
"email": "user1@example.com",
"enabled": true,
"attributes": {
"department": "IT",
"location": "New York"
}
}