跳转至

免登设置

免登设置用于让受信任的第三方系统携带加密凭证访问 CAN。CAN 校验请求路径、租户和加密凭证后,会为已存在的用户建立登录会话,从而无需在该次跳转中再输入账号和密码。

本文面向两类读者:负责配置的管理员,以及负责生成加密凭证和跳转链接的第三方系统开发者。

重要:免登设置与 OAuth、飞书、钉钉等单点登录配置是不同能力。本文仅说明「系统集成 → 免登设置」中的 URL 白名单与加密凭证方案。

使用前准备

  • 使用具有免登设置查看和管理权限的账号登录 CAN;平台级页面中的修改按钮仅对平台所有者开放。
  • 确认免登用户已在 CAN 中注册;若从租户级页面发起免登,该用户还必须属于目标租户。
  • 确认第三方系统可安全保存密钥或公钥,并通过 HTTPS 发起跳转。
  • 先确定需要免登的目标路径和目标租户 ID。白名单匹配的是 URL 路径,不包含域名和查询参数。

管理员配置

进入页面

在 CAN 中依次进入 管理设置 → 系统集成 → 免登设置。页面由以下两部分组成:

  • URL 配置:维护允许携带免登凭证访问的路径白名单;
  • 加密配置:选择加密算法、生成并复制 Key,以及验证第三方生成的加密内容。

当前租户页面保存的是该租户的专属配置;若从平台管理页面进入,页面说明会提示该配置对所有租户生效。请在实际使用的入口完成配置,并让第三方使用同一范围内生成的 Key。

配置 URL 白名单

  1. 在「白名单」区域单击 +
  2. 输入需要开放的 URL 路径,例如 /open/entry,然后确认。
  3. 可继续添加其他路径;重复路径不会重复加入。
  4. 确认列表无误后,单击页面右下角的 保存

保存会以当前页面中的完整列表覆盖已保存的白名单。单击 重置 可放弃未保存的列表修改,恢复为最近一次加载的配置。

白名单使用 Spring Ant 风格路径匹配,可按下表配置。

规则 匹配示例 适用场景
/open/entry 仅匹配 /open/entry 只开放一个明确入口,优先推荐。
/open/* 可匹配 /open/a,不匹配 /open/a/b 开放一个目录下的单层页面。
/open/** 可匹配 /open/a/open/a/b 需要开放该目录及其子路径时使用。
/** 匹配任意路径 风险很高,除非经过安全评审,否则不要使用。

安全建议:白名单只决定哪些路径可触发免登处理,并不等同于向匿名用户开放业务数据。仍应按最小范围配置;不要将登录页、管理页或整站路径加入白名单。

选择算法并生成 Key

在「加密配置」中选择 RSAAES,然后单击 生成 Key。生成操作会立即替换当前算法的旧密钥,页面会重新加载配置;Key 在页面上默认脱敏显示,可通过复制图标复制完整值。

算法 CAN 当前实现 第三方需要保存的内容 建议
RSA 2048 位密钥对,RSA/ECB/PKCS1Padding 页面展示的 Base64 公钥(X.509 编码) 优先使用。第三方只需保管公钥,私钥留在 CAN。
AES 256 位密钥,AES/GCM/NoPadding,128 位认证标签 页面展示的 Base64 对称密钥 仅在第三方能妥善保护共享密钥时使用。

当前版本的 AES 实现使用固定的 12 字节 GCM IV:w7ZdfXjV+o+L(Base64)。第三方使用 AES 时,必须使用该 IV、128 位 GCM Tag 和 UTF-8 明文;加密结果为 Base64 字符串。

警告:生成 Key 后,使用旧 Key 生成的免登链接会失效。请先在第三方系统更新 Key、完成联调和回归验证,再停止旧链接的投放。不要通过即时通信工具、工单正文或浏览器地址栏长期保存 AES Key。

使用解密测试联调

  1. 请第三方按下文的载荷和算法生成一段密文。
  2. 将密文的 Base64 原始值粘贴到「输入加密 URL 进行解密测试」输入框。若从完整跳转链接复制,请取 certification 参数 URL 解码后 的值,而不是整条 URL。
  3. 单击 解密测试
  4. 显示「验证通过」时,确认弹窗中的「解密后的原始内容」与第三方发送的 JSON 完全一致;可复制该内容用于比对。

出现「验证失败」通常表示算法、Key、RSA 填充方式、AES IV/Tag 或 Base64 编码方式不一致。完成验证后再保存白名单并进行真实跳转测试。

第三方系统接入

免登请求格式

第三方请求的目标路径必须已加入白名单,并在查询参数中传递以下字段:

参数 必填 说明
tenantId 目标租户 ID。CAN 按此值定位租户和对应的免登配置。
certification 对免登载荷加密后得到的 Base64 密文;放入 URL 时必须进行 URL 编码。

免登载荷是 UTF-8 编码的 JSON,字段如下:

{
  "account": "third-party-user",
  "timestamp": 1760000000000
}
字段 说明
account CAN 中已注册的用户账号;租户级免登时,该用户还必须已加入目标租户。
timestamp 生成密文时的 Unix 毫秒时间戳。服务端拒绝未来时间戳和生成超过 5 分钟的凭证。

完整链接形式如下,其中密文必须用标准 URL 编码处理,避免 Base64 中的 +/= 被浏览器或网关误解析:

https://can.example.com/open/entry?tenantId=<目标租户ID>&certification=<URL编码后的Base64密文>

/open/entry 仅为示例,必须替换为管理员实际加入白名单的路径。CAN 在该路径的请求中成功解析凭证后会写入登录会话,并继续处理原请求。

加密规则

第三方应先将载荷序列化为紧凑 JSON,再按管理员选定的算法加密,并将加密结果 Base64 编码。

RSA

使用管理员从页面复制的 Base64 公钥,按 X.509 公钥格式解析;加密参数固定为:

算法:RSA/ECB/PKCS1Padding
密钥:页面展示的 Base64 公钥(2048 位)
明文编码:UTF-8
输出:加密字节的标准 Base64 字符串

CAN 使用对应的私钥解密,因此第三方无需、也不应获取私钥。

AES

使用管理员从页面复制的 Base64 对称密钥,按以下参数加密:

算法:AES/GCM/NoPadding
密钥:页面展示的 Base64 值,Base64 解码后作为 AES-256 Key
IV:w7ZdfXjV+o+L(Base64,解码后为 12 字节)
GCM Tag:128 位
明文编码:UTF-8
输出:加密结果(含 GCM Tag)的标准 Base64 字符串

以下 Python 示例展示 AES 密文的生成方式。示例依赖 cryptography 库,生成后仍需对结果进行 URL 编码。

import base64
import json
import time
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from urllib.parse import quote

key_b64 = "<从CAN复制的AES Key>"
tenant_id = "<目标租户ID>"
payload = {
    "account": "third-party-user",
    "timestamp": int(time.time() * 1000),
}

key = base64.b64decode(key_b64)
iv = base64.b64decode("w7ZdfXjV+o+L")
plaintext = json.dumps(payload, separators=(",", ":")).encode("utf-8")
ciphertext = base64.b64encode(AESGCM(key).encrypt(iv, plaintext, None)).decode("ascii")
url = f"https://can.example.com/open/entry?tenantId={quote(tenant_id)}&certification={quote(ciphertext, safe='')}"

验收清单

  • 目标路径已加入白名单,且规则范围符合最小授权原则。
  • 页面显示的算法与第三方加密算法一致。
  • 第三方使用的是最新 Key;若刚轮换 Key,旧链接已停止使用。
  • 解密测试显示「验证通过」,且解密出的 accounttimestamp 与原始载荷一致。
  • account 对应用户存在,且在目标租户中可用。
  • 实际链接包含 URL 编码后的 certification 和正确的 tenantId,并在生成后 5 分钟内访问。
  • 使用 HTTPS 访问,且浏览器、网关、日志和监控系统不会记录完整的 certification 参数。

常见问题

已加白名单,但访问后仍未登录

检查实际请求的路径是否与白名单规则匹配。匹配时只使用 URL 路径;域名、查询参数和 tenantId 不参与匹配。还要确认链接包含 tenantIdcertification 两个参数,且用户已存在并属于目标租户。

解密测试失败

依次检查:是否选对 RSA/AES、是否使用最新 Key、RSA 是否为 RSA/ECB/PKCS1Padding、AES 是否为 GCM 模式且 IV/Tag 设置正确、密文是否为标准 Base64,以及粘贴的内容是否是 URL 解码后的密文值。

链接刚生成就失效

timestamp 必须是生成密文时的毫秒时间戳,不能晚于 CAN 服务端当前时间,且服务端只接受 5 分钟内的凭证。请校准第三方服务器时钟,并在跳转前即时生成链接,不要缓存或复用旧链接。

更换算法或重新生成 Key 后如何处理

算法切换或 Key 轮换会使原有的加密方式不再匹配。先将新的算法参数和 Key 安全地交付给第三方,在解密测试和测试环境验证通过后,再切换生产跳转链接;必要时安排短暂维护窗口,避免用户继续使用旧链接。