You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在自定义Keycloak协议映射器中访问claim_token信息?

在Keycloak自定义协议映射器中合法获取UMA请求的claim_token或授权信息

可行方案

方案1:利用Post Authentication Flow传递数据

协议映射器执行时机早于UMA授权逻辑,但Post Authentication Flow在授权完成后触发,可以先在这里处理claim_token并暂存数据,再让映射器读取:

  1. 进入Keycloak控制台目标Realm的「Authentication」→「Flows」,复制现有认证流(如Browser)创建自定义流。
  2. 在流的末尾添加「Script Execution」步骤,类型选择「Authentication Script」。
  3. 编写脚本提取claim_token并调用内部接口:
    // 从请求表单获取claim_token
    def claimToken = context.getHttpRequest().getDecodedFormParameters().getFirst("claim_token");
    if (claimToken != null) {
        // 调用内部接口获取departments数据
        def departments = callInternalApi(claimToken);
        // 存入用户会话
        context.getSession().setAttribute("departments", departments);
    }
    
  4. 将目标客户端的认证流切换为这个自定义流。
  5. 自定义协议映射器中从会话读取数据:
    @Override
    public void setClaim(OIDCToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession, KeycloakSession keycloakSession, ClientSessionContext clientSessionContext) {
        Object departments = userSession.getAttribute("departments");
        if (departments != null) {
            token.getOtherClaims().put("departments", departments);
        }
    }
    

方案2:扩展UMA Authorization Grant Handler

直接扩展Keycloak的UMA授权处理逻辑,在授权过程中把claim_token的处理结果绑定到授权对象:

  1. 创建Java类继承org.keycloak.authorization.uma.UMAAuthorizationGrant,重写createAuthorization方法:
    public class CustomUMAAuthorizationGrant extends UMAAuthorizationGrant {
        @Override
        protected Authorization createAuthorization(KeycloakSession session, AuthorizationRequest request) {
            Authorization authorization = super.createAuthorization(session, request);
            // 提取claim_token
            String claimToken = request.getClaimToken();
            if (claimToken != null) {
                // 调用内部接口获取部门数据
                List<String> departments = fetchDepartmentsFromInternalApi(claimToken);
                // 将数据存入授权对象的属性
                authorization.getAttributes().put("departments", departments);
            }
            return authorization;
        }
    }
    
  2. 打包成JAR部署到Keycloak的providers目录,重启Keycloak。
  3. 控制台进入「Realm Settings」→「Providers」,启用自定义的UMA授权处理器。
  4. 自定义协议映射器中直接从授权对象读取:
    @Override
    public void setClaim(OIDCToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession, KeycloakSession keycloakSession, ClientSessionContext clientSessionContext) {
        Authorization authorization = token.getAuthorization();
        if (authorization != null) {
            Object departments = authorization.getAttributes().get("departments");
            token.getOtherClaims().put("departments", departments);
        }
    }
    

方案3:使用Token Enhancer SPI

Token Enhancer的执行时机晚于授权逻辑,可直接访问授权信息并增强令牌:

  1. 实现org.keycloak.token.TokenEnhancer接口:
    public class CustomTokenEnhancer implements TokenEnhancer {
        @Override
        public AccessToken enhance(AccessToken accessToken, TokenEnhancerContext context) {
            Authorization authorization = context.getAuthorization();
            if (authorization != null) {
                String claimToken = authorization.getAuthorizationRequest().getClaimToken();
                if (claimToken != null) {
                    List<String> departments = fetchDepartmentsFromInternalApi(claimToken);
                    accessToken.getOtherClaims().put("departments", departments);
                }
            }
            return accessToken;
        }
    }
    
  2. 打包部署后,在控制台启用该Token Enhancer。

方案对比

  • Post Auth Flow:无需复杂Java扩展,脚本即可实现,适合快速验证;但会话属性存在生命周期限制,需注意清理。
  • 扩展UMA Grant Handler:完全贴合UMA流程,数据与授权强绑定,逻辑严谨,适合生产环境;需编写扩展并部署。
  • Token Enhancer:直接增强令牌,逻辑简洁,执行时机精准,扩展性强,生产环境友好。

注意:避免直接从请求表单提取claim_token的临时方案,该方式依赖请求参数的生命周期,存在被篡改或丢失的风险,官方SPI方案更稳定安全。

内容的提问来源于stack exchange,提问作者Ocramius

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 12:35:05