场景

国内企业普遍使用企业微信、飞书或钉钉作为组织协作平台,员工已经在这些平台上拥有身份。将 Keycloak 作为企业的统一 IAM 认证入口,对接这些平台的 OIDC/OAuth 能力,可以实现:

  1. 员工一键登录:内部应用使用「企业微信登录」「飞书登录」「钉钉登录」,无需额外记住密码
  2. 统一身份管理:Keycloak 作为中间层,下游应用对接 Keycloak 即可,不需要每个应用单独对接 IM 平台
  3. 混合认证:同时支持 IM 扫码登录 + 本地密码登录 + LDAP 登录等多种方式

适用场景

  • 企业内部应用需要对接企业微信、飞书或钉钉登录
  • 已有 Keycloak 作为 IAM 中心,想复用现有架构而非每应用单独适配 IM SDK
  • 需要统一管理不同 IM 来源的用户(部分员工用企业微信,部分用飞书)
  • 新员工入职后自动在 Keycloak 中创建用户(Just-In-Time Provisioning)

协议选型提示:在对接前,建议先了解 IAM 中 OIDC 和 SAML 的适用场景差异——详见 IAM 协议选型指南。国内 IM 平台中,飞书对标准 OIDC 的支持最成熟,企业微信和钉钉需要额外适配。

不适用场景

  • 只需要在单一应用中对接 IM 登录——直接用 IM 的 OAuth SDK 更快,Keycloak 中间层反而增加复杂度
  • 对外 C 端用户登录——企业微信和钉钉的 OAuth 登录通常限定组织内成员
  • 需要极致的移动端体验——IM 平台原生 SDK 在某些场景下比 OIDC 重定向流程更流畅

总体架构

  flowchart LR
    subgraph "用户"
        U[员工]
    end

    subgraph "IM 平台"
        WX[企业微信<br/>OIDC Provider]
        FS[飞书<br/>OIDC Provider]
        DD[钉钉<br/>OIDC Provider]
    end

    subgraph "Keycloak IAM"
        KC[Keycloak<br/>OIDC/SAML Broker]
    end

    subgraph "下游应用"
        A1[内部系统 A]
        A2[内部系统 B]
        A3[Kubernetes Dashboard]
    end

    U -->|扫码/账号登录| WX
    U -->|扫码/账号登录| FS
    U -->|扫码/账号登录| DD

    WX -->|OIDC| KC
    FS -->|OIDC| KC
    DD -->|OIDC| KC

    KC -->|OIDC/SAML| A1
    KC -->|OIDC/SAML| A2
    KC -->|OIDC| A3

Keycloak 在这一架构中扮演 **Identity Broker(身份中介)**角色:对外对接多个上游 IM 平台的 OIDC,对内向下游应用统一暴露 OIDC/SAML 接口。下游应用不需要知道用户来自哪个 IM 平台。

三平台对比速览

平台协议支持应用创建入口用户标识字段文档入口
企业微信OAuth 2.0企业微信管理后台 → 应用管理 → 自建应用UserId(企业内唯一)open.work.weixin.qq.com
飞书OIDC(推荐)/ OAuth 2.0飞书开放平台 → 创建企业自建应用open_id / union_idopen.feishu.cn
钉钉OAuth 2.0 / OIDC(新版)钉钉开放平台 → 创建应用openId / unionIdopen.dingtalk.com

三平台均在向标准 OIDC 协议靠拢。飞书的 OIDC 支持最成熟(Discovery Endpoint、标准 claims)。企业微信和钉钉传统上使用自有 OAuth 2.0 变体,但 Keycloak 可以通过 Generic OIDC Provider 或自定义 Identity Provider 对接。

通用配置步骤

以下步骤适用于所有三个平台。平台特定差异在后续小节说明。

第一步:在 IM 平台创建 OAuth 应用

核心信息需要记录:

配置项说明示例
应用名称IM 平台中显示「内部系统统一登录」
回调地址(Redirect URI)Keycloak 的 broker endpointhttps://sso.example.com/realms/example/broker/wecom/endpoint
可信域名部分平台要求配置sso.example.com

回调地址格式:https://<keycloak-host>/realms/<realm-name>/broker/<idp-alias>/endpoint

其中 <idp-alias> 是你在 Keycloak 中配置的 Identity Provider 别名(如 wecom、feishu、dingtalk)。

第二步:在 Keycloak 中添加 Identity Provider

进入 Keycloak 管理控制台 → 选择 Realm → Identity Providers → 选择 OpenID Connect v1.0。

基础配置:

配置项说明
Alias唯一标识,如 wecom。决定了回调地址路径
Display Name登录页显示名称,如「企业微信登录」
EnabledON
Store Tokens建议 ON(便于调试 token 内容)
Trust Email根据平台决定(企业微信可能不返回已验证邮箱)

第三步:配置 OIDC 端点

三个平台的 OIDC 端点如下表:

端点企业微信飞书钉钉(新版 OIDC)
Authorization URLhttps://open.weixin.qq.com/connect/oauth2/authorizehttps://passport.feishu.cn/suite/passport/oauth/authorizehttps://login.dingtalk.com/oauth2/auth
Token URLhttps://qyapi.weixin.qq.com/cgi-bin/gettoken(非标准,需二步获取)https://passport.feishu.cn/suite/passport/oauth/tokenhttps://api.dingtalk.com/v1.0/oauth2/userAccessToken
User Info URLhttps://qyapi.weixin.qq.com/cgi-bin/user/getuserinfohttps://passport.feishu.cn/suite/passport/oauth/userinfohttps://api.dingtalk.com/v1.0/contact/users/me
Client ID应用的 CorpId + 自建应用凭据飞书应用的 App ID钉钉应用的 Client ID
Client Secret自建应用的 Secret飞书应用的 App Secret钉钉应用的 Client Secret

⚠️ 企业微信用户信息端点差异:企业微信的 /getuserinfo 端点接收的参数名是 access_token 而非标准 Authorization: Bearer header,需要在 Keycloak 中自定义 User Info 请求方式或使用自定义 Identity Provider 插件(如 keycloak-services-social-weixin)。

第四步:配置属性映射(Mappers)

用户在 IM 平台的身份信息需要映射到 Keycloak 用户属性。以飞书为例:

Keycloak Mapper 配置:
  - 用户名:sub → username(或使用 open_id)
  - 邮箱:email → email
  - 姓名:name → firstName + lastName
  - 手机号:mobile → 自定义属性 phone_number

企业微信的 /getuserinfo 返回字段:

字段说明Keycloak 映射建议
UserId企业内唯一用户标识→ username 或自定义属性
DeviceId设备 ID忽略
user_ticket成员票据可选存储

飞书 OIDC UserInfo 返回字段:

字段说明Keycloak 映射建议
sub用户唯一标识→ username
name用户姓名→ firstName + lastName(需拆分)
email邮箱→ email(需确认已配置邮箱权限)
mobile手机号(需申请权限)→ 自定义属性
avatar_url头像 URL→ 自定义属性

飞书 OIDC 集成详解(推荐起点)

飞书对标准 OIDC 协议的支持最完整,推荐作为第一个对接的平台。

飞书开放平台配置

  1. 登录 飞书开放平台,创建企业自建应用
  2. 在「安全设置」中添加重定向 URL:https://sso.example.com/realms/example/broker/feishu/endpoint
  3. 在「权限管理」中开启以下权限:
    • contact:user.email:readonly(获取邮箱)
    • contact:user.phone:readonly(获取手机号,按需)
    • contact:user.base:readonly(获取基本信息)
  4. 发布应用并获得管理员审批

Keycloak 飞书 IdP 配置

# 在 Keycloak 管理界面配置,此处用配置结构展示
Alias: feishu
Display Name: 飞书登录
Enabled: true

# OIDC 设置
Authorization URL: https://passport.feishu.cn/suite/passport/oauth/authorize
Token URL: https://passport.feishu.cn/suite/passport/oauth/token
User Info URL: https://passport.feishu.cn/suite/passport/oauth/userinfo
Client ID: cli_xxxxxxxxxxxx
Client Secret: xxxxxxxxxxxxxxxxxxxxxxxx

# 高级设置
Scopes: openid profile email phone
Prompt: consent
Validate Signatures: false  # 飞书暂不支持 JWKS 验证,使用 UserInfo 端点确认

验证

配置完成后,访问 Keycloak 的账号管理页面,应能看到「飞书登录」按钮:

# 1. 检查 IdP 重定向端点是否可达
curl -I "https://sso.example.com/realms/example/broker/feishu/endpoint"
# 应返回 302 重定向到 passport.feishu.cn

# 2. 在浏览器中访问,应跳转到飞书登录页面
# https://sso.example.com/realms/example/account
# → 点击「飞书登录」→ 飞书授权页 → 授权后回到 Keycloak

企业微信集成(自定义 IdP 方式)

企业微信的 OAuth 2.0 不是标准 OIDC,不能直接用 Keycloak 内置的 OIDC Identity Provider。有两种方案:

方案 A:使用社区插件

GitHub 上有针对企业微信的 Keycloak 插件,封装了非标准 API 调用:

# 社区插件示例(需验证兼容性)
# https://github.com/joe-stifler/keycloak-services-social-weixin

部署方式:将 JAR 放入 providers/ 目录,重启 Keycloak,在 Identity Providers 列表中选择新增的「WeChat Work」类型。

方案 B:通过企业微信 OAuth 2.0 代理(推荐)

如果无法使用社区插件,更可靠的方式是在 Keycloak 前放置一个轻量的 OAuth 2.0 → OIDC 转换代理:

  flowchart LR
    KC[Keycloak] -->|OIDC| PROXY[OAuth2-OIDC 适配器]
    PROXY -->|企业微信 API| WX[企业微信]

可以使用 Dex、oauth2-proxy 或一个简单的 Flask/Express 服务将企业微信的非标准 OAuth 封装成标准 OIDC 端点,然后 Keycloak 作为标准 OIDC IdP 接入。

钉钉集成

钉钉在 2023 年后逐步支持标准 OIDC 协议。新版应用(钉钉开放平台 2.0)可以使用标准 OIDC 接入。

钉钉开放平台配置

  1. 登录 钉钉开放平台,创建企业内部应用
  2. 在「开发管理」中添加回调域名
  3. 记录 Client ID 和 Client Secret

Keycloak 钉钉 OIDC 配置要点

钉钉的 OIDC 支持仍在演进中,如果标准 OIDC 端点不可用,可回退到 Generic OAuth 2.0 Provider 模式:

参数值
Authorization URLhttps://login.dingtalk.com/oauth2/auth
Token URLhttps://api.dingtalk.com/v1.0/oauth2/userAccessToken
User Info URLhttps://api.dingtalk.com/v1.0/contact/users/me
Client ID应用 Client ID
Scopeopenid corpid

常见错误与排错

错误现象可能原因解决方案
redirect_uri_mismatchIM 平台配置的回调地址与 Keycloak Broker Endpoint 不一致检查两端的完整 URL,特别注意 http vs https、尾部斜杠
invalid_clientClient ID/Secret 错误或应用未发布到 IM 开放平台确认凭据、确认应用已发布上线
登录后 Keycloak 显示「用户已存在」邮箱已被其他 IdP 或本地用户占用检查 Trust Email 设置,或为不同 IdP 来源的用户设置不同的用户名生成策略
飞书返回邮箱为空未申请 contact:user.email 权限或未审批到飞书开放平台的「权限管理」中申请并发布
企业微信 redirect 后卡住企业微信 OAuth 是二步流程,Keycloak 标准 OIDC IdP 无法直接处理使用社区插件或自建 OAuth2-OIDC 代理
钉钉 userAccessToken 接口返回权限不足应用未申请 Contact.User.Read 权限到钉钉开放平台申请权限并发布
回调后出现 Identity Provider email not verifiedIM 平台返回的 email 未标记 verified在 Keycloak IdP 设置中开启「Trust Email」,或调整 First Login Flow 跳过邮箱验证

用户属性映射最佳实践

# 推荐的用户名生成策略(避免冲突)
# 不同 IdP 来源的用户使用不同前缀
user_pre:
  # 飞书用户: sub(open_id)
  feishu → feishu_${CLAIM.sub}
  # 企业微信用户: UserId
  wecom → wecom_${CLAIM.UserId}
  # 钉钉用户: openId
  dingtalk → dingtalk_${CLAIM.openId}

# 邮箱: 优先使用 IM 平台已验证邮箱(需确认平台是否验证)
email → ${CLAIM.email}

# 部门/组织信息(用于自动分组)
department → ${CLAIM.department}

自动分配用户组

可以通过 Keycloak 的 Identity Provider Mapper 将 IM 平台的部门信息映射到 Keycloak Group:

  1. 创建「Advanced Attribute to Group」类型的 Mapper
  2. 将飞书的 department_ids 或企业微信的 department 字段映射到 Keycloak 已有 Group
  3. 新用户首次登录时自动加入对应 Group

生产环境注意事项

  1. 证书与 HTTPS:所有回调 URL 必须使用 HTTPS。Keycloak 部署在反向代理后时,确保反向代理正确设置了 X-Forwarded-Proto 和 X-Forwarded-Host headers
  2. 令牌刷新:IM 平台的 access_token 有效期通常较短(2 小时),Keycloak 会自动处理 refresh(如果平台支持)
  3. 用户注销:Keycloak 登出时,是否需要同步注销 IM 平台?通常不需要——IM 平台的会话独立管理,只需注销 Keycloak 自身会话
  4. 多平台并存:如果同时对接企业微信和飞书,确保两个 IdP 的用户名生成策略不会冲突(见上文前缀方案)
  5. 速率限制:IM 平台通常有 API 调用频率限制。大规模用户集中登录(如早晨上班高峰)时,Keycloak 自带的缓存可以减轻对 IM 平台的压力——User Info 结果会被缓存
  6. 权限审批:飞书和钉钉的某些权限(如手机号)需要平台管理员审批,提前申请避免上线时被卡

回滚方式

如果集成出现问题:

# 1. 禁用 IdP(不删除,保留配置)
# Keycloak Admin Console → Identity Providers → 选择 IdP → Enabled: OFF

# 2. 清除已创建的用户(如果需要)
# 通过 Admin CLI 批量清理特定 IdP 来源的用户

# 3. 或者通过修改 First Login Flow 拒绝该 IdP 的新用户创建
# Authentication → Flows → First Broker Login → 在「Create User If Unique」后添加拒绝条件

禁用 IdP 不会影响已通过该 IdP 创建的用户——他们仍可正常登录(如果设置了密码)或通过其他 IdP 登录。

小结

将企业微信、飞书、钉钉作为 Keycloak 的上游 Identity Provider,是让企业内部应用「一键登录」最少的维护成本方案。飞书的 OIDC 支持最成熟,推荐优先对接;企业微信和钉钉需要额外适配,但收益同样明显——员工用自己每天都在用的 IM 账号登录内部系统,无需额外记忆密码,IT 团队不需要维护独立的密码数据库。

常见问题(FAQ)

三个平台能同时接入吗?

可以。Keycloak 支持配置多个 Identity Provider。用户在登录页面会看到多个登录选项(企业微信登录、飞书登录、钉钉登录),任选其一即可。

员工的 IM 账号被禁用后,还能登录内部系统吗?

取决于 Keycloak 的配置。默认情况下,如果 IM 平台拒绝认证(用户被禁用、离职),用户无法通过该 IdP 登录 Keycloak。但用户在 Keycloak 中的账户仍然存在,如果设置了独立的密码或其他 IdP 绑定,仍可通过其他方式登录。

如何限制只有特定部门的员工才能登录?

在 Keycloak IdP 配置中,可以在 Post Broker Login Flow 中添加一个「Script Mapper」或条件判断,检查用户的部门属性是否在允许列表中。或者更简单的方式:在 IdP Mapper 中将部门映射到 Group,然后在下游应用的 Keycloak Client 中配置只有特定 Group 可以访问。

Keycloak 本身需要对接 AD/LDAP 吗?

不冲突。Keycloak 可以同时配置多个 User Federation(如 LDAP/AD)和多个 Identity Provider(如飞书/企业微信)。用户可以先通过飞书登录,Keycloak 自动创建本地用户;如果用户也存在于 LDAP 中,可以通过属性匹配(如邮箱)自动关联。