亚马逊AWS官方博客

使用飞书实现 Amazon Quick 统一单点登录(Web + Desktop)

摘要:飞书授权登录并非标准 OIDC,无法直接作为 Amazon Quick 的 IdP。本文介绍一个开源的全 Serverless 参考实现:用 Lambda + API Gateway 构建飞书 OIDC 适配器,KMS 非对称密钥签发 id_token,以 Cognito 为身份枢纽,实现 Quick Web 与 Desktop 的飞书统一单点登录。


一、背景

Amazon Quick 目前提供两种客户端形态:

  • Amazon Quick Web:浏览器访问,支持 IAM Identity Center、IAM federation 等多种身份类型;
  • Amazon Quick Desktop:桌面客户端,企业版部署仅支持标准 OpenID Connect(OIDC)协议对接企业身份源。用户点击 “Continue with SSO” 后,客户端拉起浏览器跳转到企业 IdP 的授权端点,通过授权码 + PKCE 换取令牌,Quick 校验令牌后按邮箱精确匹配将用户映射到 Quick 账户(参见官方文档)。

官方目前提供了 Microsoft Entra ID、Google Workspace、Okta、Ping Identity 四种 IdP 的对接指南。然而在中国区客户的实际场景中,飞书(Feishu/Lark)是最普遍的企业 IM 与协作平台之一,大量客户没有部署 Entra ID、Okta 这类企业 IdP,员工的唯一企业身份就是飞书账号。因此“用飞书登录 Amazon Quick”成为一个高频需求。

问题在于:飞书开放平台的网页授权登录并不是标准 OIDC 协议,无法直接作为 Quick Desktop 的 IdP 使用。

二、挑战:飞书授权登录与标准 OIDC 的差距

Quick Desktop 作为标准 OIDC 公共客户端(Public Client + PKCE),对 IdP 有一套硬性要求。逐项对照飞书开放平台的获取用户凭证能力,差距如下:

标准 OIDC 要求 飞书开放平台现状
/.well-known/openid-configuration 发现文档
授权码换取 JWT 格式的 id_token 换取的是自有格式的 user_access_token,非 JWT
JWKS 端点公开签名公钥,供客户端验签
标准 claims(sub/email/iss/aud/exp…) 用户信息需另行调用 /user_info 接口获取
标准 scope 语义(openid/email/profile 使用飞书自有权限体系(如 contact:user.email:readonly

也就是说,飞书提供的是 OAuth 2.0 风格的授权 + 私有用户信息 API,缺少 OIDC 的“身份令牌”层。要让 Quick Desktop(以及任何标准 OIDC 依赖方)认得飞书,必须在中间补齐这一层协议转换。

三、解决方案

我们开源了一个全 Serverless 的参考实现:sample-for-amazon-quick-sso-with-feishu。核心思路是:

1. 自建一个“飞书 OIDC 适配器”(Lambda + API Gateway),把飞书授权登录包装成标准 OIDC IdP:对外暴露 /.well-known/openid-configuration/authorize/token/jwks.json 等标准端点;

2. 用 Amazon Cognito User Pool 作为身份枢纽,将适配器注册为 Cognito 的联邦 OIDC IdP——Quick Desktop 和 Quick Web 都对接 Cognito,而不是直接对接飞书;

3. Quick Web 侧再加一个登录门户 Lambda,走 Cognito OIDC 授权码流拿到用户邮箱后,通过 IAM federation(sts:AssumeRole + 联邦登录端点)把用户直接送进 Quick Web。

整套方案无数据库、无常驻服务器,资源清单只有:两个 Lambda + 两个 API Gateway、一个 Cognito User Pool、一把 KMS 非对称密钥、一个 IAM 联邦角色。

3.1 架构

[图1 部署架构图]

认证链路(图中编号):用户在浏览器完成一次飞书扫码/授权(①),飞书回调授权码到适配器(②),适配器 Lambda 用授权码换取飞书用户信息、经 KMS 签出标准 OIDC id_token 交给 Cognito(③);Quick Desktop 经剥离代理走 OIDC + PKCE 从 Cognito 拿到令牌(④);Quick Web 侧门户 Lambda 验完 id_token 后 AssumeRole 换取联邦登录会话并 302 跳转进入 Quick(⑤)。

3.2 关键设计点

1. 用 KMS 非对称密钥签发 id_token,私钥不出 KMS

适配器收到 Cognito 转来的授权码后,调用飞书接口换取 user_access_token、读取 /user_info,然后把用户信息组装成标准 OIDC claims,用 AWS KMS 的 RSA 非对称密钥执行 kms:Sign 签出 JWT 格式的 id_token。JWKS 端点通过 kms:GetPublicKey 动态导出公钥——签名私钥全生命周期不离开 KMS,无需在代码或环境变量中保存任何签名密钥。

2. sub 声明的选择:union_id 优先

飞书用户有 open_id(应用内唯一)和 union_id(开发商维度唯一)两种标识。方案默认使用 union_id 作为 OIDC sub:即使日后更换飞书应用,用户身份依然稳定,不会导致 Cognito 重新预置所有用户。该选择一经部署不可逆,需要在规划阶段确定。

3. 邮箱兜底:通讯录 API

Quick 按邮箱精确匹配用户,因此 email claim 必须拿到。部分企业用户只在飞书通讯录里配置了企业邮箱,/user_info 接口返回不了。适配器内置了兜底逻辑:取不到邮箱时自动用 tenant_access_token 调用通讯录 API 补齐,并支持企业邮箱/工作邮箱的优先级配置。

4. Quick Desktop 的 offline_access 剥离代理

实测发现 Quick Desktop 发起授权时会强制携带 offline_access scope,而 Cognito 不支持该 scope,会直接报错。适配器因此内置了一个 /cognito/* 透明代理:剥离 offline_access 后再转发给 Cognito 的授权/令牌端点。Quick Desktop 的 extension 配置指向这个代理端点即可。

5. Quick Web:IAM federation + Email 会话标签

Web 登录门户对同一个 Cognito User Pool 跑标准 OIDC 授权码流,校验 id_token 拿到邮箱后,调用 sts:AssumeRole 扮演 Quick 联邦角色并打上 Email 会话标签,再通过 AWS 联邦登录端点(getSigninToken)换取控制台会话,最后 302 跳转进 Quick Web。用户全程只见到一次飞书扫码/授权页。

6. 单点登录的本质:共享 IdP 浏览器会话

Web 和 Desktop 的 SSO 不是靠共享 token,而是靠浏览器里共享的飞书/Cognito 会话 Cookie。登录任一侧后,在 Quick Desktop 内点击 Web 深链接(如 More → Chat agents)时会复用该会话,无需二次认证。

四、部署步骤

4.1 前提条件

  • 飞书自建应用:开通并发布 contact:user.email:readonlycontact:user.employee:readonly 权限,可用范围覆盖使用 Quick 的成员,记下 App ID 与 App Secret;
  • Amazon Quick Enterprise 账户,身份类型为 IAM federation;
  • Node.js 18+、Python 3.12+、AWS CDK v2。

4.2 一键部署

git clone https://github.com/aws-samples/sample-for-amazon-quick-sso-with-feishu.git
cd sample-for-amazon-quick-sso-with-feishu
npm install
npx cdk bootstrap                              # 每个账号/区域一次
npx cdk deploy -c feishuAppId=cli_xxxxxxxxxxxx

飞书 App Secret 通过脚本写入 AWS Secrets Manager,不进代码、不进 CDK context:

python3 scripts/set_feishu_secret.py --app-secret <FEISHU_APP_SECRET>

冒烟测试:

python3 scripts/verify_deployment.py

之后在飞书开放平台回填重定向 URL,在 Quick 管理控制台按官方四步流程(创建 extension access → 创建 extension → 分发桌面端)完成 Desktop 配置,Web 侧将门户 URL 分发给用户即可。完整参数(Lark 海外版端点、sub/email claim 策略、来源 IP 限制、资源保留策略等)见仓库 README。

五、安全考虑

  • 签名密钥:id_token 由 KMS 非对称密钥签发,私钥不可导出;删除堆栈时密钥进入计划删除,可用 -c retain=true 保留。
  • 网络暴露面:两个 API Gateway 默认公开(OIDC 端点本身需要被浏览器访问)。生产环境建议用 -c allowedCidrs 配置资源策略限制来源 IP,或挂载 AWS WAF
  • 最小权限:Quick 联邦角色默认授予 quicksight:* 以保证开箱可用,README 明确建议按最小权限收敛;其信任策略已限定为仅门户 Lambda 角色可扮演。
  • 会话与离职回收:门户经角色链 AssumeRole,会话上限 1 小时,到期静默续期;Cognito refresh token 有效期内不会回飞书重新校验,员工离职时应缩短有效期或禁用对应 Cognito 用户。
  • 合规基线:项目已集成 cdk-nagAwsSolutionsChecks)并通过全部检查,所有例外均在代码中标注了理由。

六、总结

通过一个轻量的 Serverless OIDC 适配层,我们把飞书的私有授权协议转换成了标准 OIDC,让 Amazon Quick 的 Web 端和 Desktop 端共享同一套飞书身份体系:用户一次飞书授权,即可无缝使用 Quick 全家桶。该模式不仅适用于 Quick——任何要求标准 OIDC IdP 的服务(IAM Identity Center 外部 IdP、第三方 SaaS 等),都可以复用这个“飞书 → OIDC”适配器。

完整源码与部署手册: https://github.com/aws-samples/sample-for-amazon-quick-sso-with-feishu

➡️ 下一步行动:

相关产品:

相关文章:

七、参考链接

*前述特定亚马逊云科技生成式人工智能相关的服务目前在亚马逊云科技海外区域可用。亚马逊云科技中国区域相关云服务由西云数据和光环新网运营,具体信息以中国区域官网为准。

本篇作者

黎小为

亚马逊云科技解决方案架构师,负责亚马逊云科技解决方案构建,在加入亚马逊云科技之前,就职于腾讯、网易、京东等国内大型互联网企业,在GenAI 应用方面有丰富的经验。

彭赟

AWS资深解决方案架构师,负责基于AWS的云计算方案架构咨询和设计,20多年软件架构、设计、开发、项目管理交付经验,擅长业务咨询、产品设计、软件架构,在大数据、区块链、容器化方向有较深入的研究,具有丰富的解决客户实际问题的经验。


AWS 架构师中心:云端创新的引领者

探索 AWS 架构师中心,获取经实战验证的最佳实践与架构指南,助您高效构建安全、可靠的云上应用