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

Keycloak自定义身份提供商用户认证问题求助

Keycloak自定义身份提供商:AuthenticationSession缺失问题解决

问题分析

自定义身份提供商的回调环节中,session.getContext().getAuthenticationSession()返回空、callback.getAndVerifyAuthenticationSession()无法工作,核心原因是AuthenticationSession未被正确关联到回调请求。Keycloak依赖state参数绑定登录发起时创建的认证会话,回调时需要通过该参数找回会话,才能完成后续认证流程。

解决步骤

1. 在performLogin中生成并传递state参数

登录发起时,创建并存储state到AuthenticationSession,同时将state作为参数重定向到你的服务:

@Override
public Response performLogin(AuthenticationRequest request, IdentityProviderModel model) {
    // 获取当前认证会话
    AuthenticationSessionModel authSession = request.getAuthenticationSession();
    // 生成唯一state值
    String state = KeycloakModelUtils.generateId();
    // 将state存入认证会话的临时备注中
    authSession.setAuthNote("CUSTOM_IDP_STATE", state);
    
    // 构造重定向到你的服务的URL,携带state和回调地址
    String redirectUri = UriBuilder.fromUri("https://your-service.com/your-login-endpoint")
            .queryParam("state", state)
            .queryParam("redirect_uri", request.getRedirectUri())
            .build().toString();
            
    return Response.seeOther(URI.create(redirectUri)).build();
}

2. 在回调Endpoint中通过state找回AuthenticationSession

从回调请求中提取state,用它定位对应的认证会话,再构造BrokeredIdentityContext完成认证:

@GET
@Path("callback")
public Response callback(@QueryParam("state") String state, 
                         @QueryParam("user_id") String userId,
                         @QueryParam("username") String username,
                         @QueryParam("email") String email) {
    KeycloakSession session = context.getKeycloakSession();
    RealmModel realm = session.getContext().getRealm();
    
    // 通过state查找认证会话(第三个参数是你的身份提供商ID)
    AuthenticationSessionModel authSession = session.sessions()
            .getAuthenticationSessionByClientNote(realm, "CUSTOM_IDP_STATE", state);
            
    if (authSession == null) {
        return Response.status(Response.Status.BAD_REQUEST)
                .entity("无效的state参数,认证会话不存在")
                .build();
    }
    
    // 构造BrokeredIdentityContext,关联认证会话
    BrokeredIdentityContext identity = new BrokeredIdentityContext(userId);
    identity.setUsername(username);
    identity.setEmail(email);
    identity.setAuthenticationSession(authSession);
    identity.setRealm(realm);
    identity.setIdpConfig(session.getContext().getIdentityProvider());
    
    // 调用callback完成认证
    IdentityProviderCallback callback = session.getProvider(IdentityProviderCallback.class);
    return callback.authenticated(identity);
}

3. 关键注意事项

  • state参数的唯一性:必须保证每个登录请求的state唯一,避免会话冲突
  • 提供商ID匹配:查找AuthenticationSession时使用的提供商ID,要与你在Keycloak后台配置的身份提供商ID一致
  • BrokeredIdentityContext必填项:必须设置authenticationSession、realm、idpConfig这几个核心属性,否则认证流程会失败

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 08:12:45