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

Keycloak身份代理可创建无效用户账户及解决方案咨询

Keycloak身份代理用户名异常问题解决方案

问题背景

使用Keycloak作为身份代理时,对接的IDP仅返回带斜杠的sub声明,无email字段。Keycloak默认会在首次登录时显示“更新账户信息”界面,用户可能直接使用含斜杠的sub作为用户名,导致账户损坏——管理UI中用户名只读且无法保存修改。

解决方案:自动清理sub斜杠并设为默认用户名

完全可以通过自定义映射逻辑实现,以下是两种可行方案:

方案1:使用Script Mapper(无需编码,快速实现)

  1. 登录Keycloak管理控制台,进入目标Realm的Identity Providers页面,选择对接的IDP
  2. 切换到Mappers标签页,点击Create
  3. 配置参数:
    • Name:自定义名称(如Clean Sub as Username)
    • Mapper Type:选择Script Mapper
    • Script Type:选择User Attribute Mapper
    • Script内容:
      // 从IDP声明中获取sub值,根据实际返回调整获取方式
      const sub = user.getAttribute('sub');
      // 移除所有斜杠
      const cleanedUsername = sub.replace(/\//g, '');
      // 设置为用户名
      user.setUsername(cleanedUsername);
      
  4. 保存后,调整该映射器的执行顺序到最顶部,确保优先于默认的用户名映射逻辑

方案2:自定义Java协议映射器(适合复杂场景)

如果Script Mapper无法满足需求,可编写自定义映射器:

  1. 创建Java类,继承AbstractOIDCProtocolMapper,重写用户信息转换方法:
    import org.keycloak.models.UserSessionModel;
    import org.keycloak.models.KeycloakSession;
    import org.keycloak.protocol.oidc.mappers.AbstractOIDCProtocolMapper;
    import org.keycloak.protocol.oidc.mappers.OIDCAccessTokenMapper;
    import org.keycloak.protocol.oidc.mappers.OIDCUserInfoMapper;
    import org.keycloak.provider.ProviderConfigProperty;
    import org.keycloak.representations.IDToken;
    
    import java.util.List;
    
    public class CleanSubUsernameMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCUserInfoMapper {
    
        public static final String PROVIDER_ID = "clean-sub-username-mapper";
    
        @Override
        public String getId() {
            return PROVIDER_ID;
        }
    
        @Override
        public String getDisplayCategory() {
            return "User Attribute";
        }
    
        @Override
        public String getDisplayType() {
            return "Clean Sub as Username";
        }
    
        @Override
        public void transformUserInfo(IDToken userInfo, ProtocolMapperModel mappingModel, UserSessionModel userSession, KeycloakSession session) {
            // 获取IDP返回的sub声明
            String sub = userSession.getUser().getFirstAttribute("sub");
            if (sub != null) {
                String cleanedUsername = sub.replaceAll("/", "");
                userInfo.setUsername(cleanedUsername);
                // 同步更新用户实体的用户名
                userSession.getUser().setUsername(cleanedUsername);
            }
        }
    
        @Override
        public List<ProviderConfigProperty> getConfigProperties() {
            return List.of();
        }
    }
    
  2. 将类打包成JAR,放入Keycloak的providers目录,执行kc.sh build(Windows用kc.bat build)后重启服务
  3. 在IDP的Mappers页面添加该自定义映射器,调整执行顺序到顶部

预防措施:跳过账户信息更新界面

若无需用户手动修改信息,可修改IDP的首次登录流程:

  1. 进入IDP配置页面,找到First Login Flow选项
  2. 选择first broker login - copy profile,跳过“更新账户信息”步骤,直接使用处理后的sub作为用户名

修复已损坏的账户

对于已经存在的无效用户名账户,可通过Keycloak Admin API修改:

# 先获取管理员Token
curl -X POST http://localhost:8080/realms/master/protocol/openid-connect/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=admin&password=admin&grant_type=password&client_id=admin-cli"

# 使用Token修改用户名
curl -X PUT http://localhost:8080/admin/realms/{你的Realm名}/users/{用户ID} \
  -H "Authorization: Bearer {管理员Token}" \
  -H "Content-Type: application/json" \
  -d '{"username": "清理后的用户名"}'

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 10:40:25