如何在Keycloak生成的Access Token(JWT)中添加自定义字段?
在Spring Boot + Keycloak环境中为Access Token添加自定义信息的解决方案
方案1:使用Keycloak内置Protocol Mapper(推荐,无需编码)
这是最简便的实现方式,直接通过Keycloak管理控制台配置即可:
- 登录Keycloak管理后台,进入目标Realm
- 左侧菜单选择
Clients,找到你的Spring Boot应用对应的客户端 - 切换至
Mappers标签页,点击Create - 根据需求选择对应Mapper类型并配置:
- 用户属性映射:选择
User Attribute类型,填写名称、Token Claim Name(如custom_user_attr),选择要映射的用户属性,勾选Add to access token - 静态固定值:选择
Hardcoded claim类型,设置名称、Claim Name、Claim Value,勾选Add to access token - 角色/Realm信息:选择
User Realm Role或其他对应类型,配置后勾选添加到Access Token
- 用户属性映射:选择
- 保存后重新获取Access Token,即可在JWT Payload中看到自定义字段
方案2:自定义Keycloak Token Provider(复杂动态逻辑场景)
如果需要根据业务逻辑动态生成自定义信息(比如从外部数据库查询),可以开发Keycloak扩展:
- 创建Java类实现
TokenProvider或继承AbstractTokenProvider:
public class CustomAccessTokenProvider extends AbstractTokenProvider { @Override public AccessToken transformAccessToken(AccessToken token, KeycloakSession session, ClientSessionContext clientSessionCtx) { // 获取当前认证用户 UserModel currentUser = session.getContext().getAuthenticationSession().getAuthenticatedUser(); // 添加动态生成的自定义字段 token.getOtherClaims().put("dynamic_custom_data", fetchCustomDataFromService(currentUser.getId())); return token; } // 示例:从外部服务获取数据 private String fetchCustomDataFromService(String userId) { // 这里实现你的业务逻辑,比如调用DB或API return "custom_value_for_" + userId; } }
- 将类打包成JAR,放入Keycloak安装目录的
providers文件夹,重启Keycloak - 在Realm配置中启用该自定义Provider(具体路径根据Keycloak版本调整,通常在
Realm Settings->Tokens或Events配置中)
方案3:Spring Boot客户端侧处理(Keycloak端无法修改时)
如果无法调整Keycloak配置,可以在Spring Boot客户端拦截并修改Token:
- 实现
TokenEnhancer接口添加自定义信息:
@Service public class ClientSideTokenEnhancer implements TokenEnhancer { @Override public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { if (accessToken instanceof DefaultOAuth2AccessToken) { DefaultOAuth2AccessToken mutableToken = (DefaultOAuth2AccessToken) accessToken; Map<String, Object> additionalClaims = new HashMap<>(mutableToken.getAdditionalInformation()); // 添加客户端侧自定义字段 additionalClaims.put("client_custom_field", "client_side_value"); mutableToken.setAdditionalInformation(additionalClaims); } return accessToken; } }
- 配置Spring Security,将该Enhancer加入Token处理流程(以资源服务器为例):
@Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Autowired private ClientSideTokenEnhancer tokenEnhancer; @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { resources.tokenServices(customTokenServices()); } private ResourceServerTokenServices customTokenServices() { DefaultTokenServices tokenServices = new DefaultTokenServices(); tokenServices.setTokenEnhancer(tokenEnhancer); // 其他必要配置,如令牌存储等 return tokenServices; } }
注意:客户端侧修改Token后,若需与其他服务交互,必须使用Keycloak的私钥重新签名,否则Token会被判定为无效。仅内部使用时可忽略签名步骤。
内容的提问来源于stack exchange,提问作者AFzal Khan
相关产品推荐
相关产品推荐

