单点登录与统一认证集成
企业上线时,常见两类需求:员工已经在企业统一门户登录,希望直接进入 RuoYi Office;或者以 RuoYi Office 作为认证入口,让其他业务应用共用员工身份。两种方向都可行,具体配置或适配范围取决于认证协议、账号映射及退出要求。
本文按当前源码说明现成能力和对接步骤,包含智能体 AgentOS 的实际集成案例。示例域名、账号和参数均用于说明;具体客户环境仍需联调验收。
一、先确定谁提供认证
认证服务负责确认“用户是谁”;接入应用信任认证结果,再按自己的业务权限提供功能。浏览器从哪个系统发起跳转,不决定谁是认证服务。
- 客户已有统一门户、身份平台:优先采用方案一。
- 客户希望围绕一体化平台接入多个应用:采用方案二。
- 两种模式也可以组合:平台先接入客户认证,再为下游应用提供授权;这需要贯通身份映射、租户和会话策略后验收。
三项需求要分别约定
单点登录解决重复登录;账号和部门同步解决人员数据一致性;统一退出解决多个应用会话的联动。配置单点登录,不代表后两项自动完成。
二、方案一:接入客户统一认证
对接流程
以客户提供 OAuth2 / OIDC 认证服务为例:
上图是对接方案示意,不代表当前版本已经实现任意 OIDC 认证服务的通用接入。CAS、SAML 等协议的票据交换方式不同。
当前能力与适配范围
平台已有第三方授权、回调、账号绑定和本系统令牌签发机制,包含企业微信、钉钉等渠道。接入客户自建认证服务时,应先核对协议,不能只填写一个认证地址就视为对接完成。
- 已有渠道:按对应平台要求配置应用凭据、回调地址和账号绑定,完成联调。
- 客户 OAuth2 服务:可复用现有第三方登录基础,适配授权地址、令牌接口、用户信息接口和字段映射。
- 客户 OIDC 服务:需要按对方规范处理身份令牌、签名与声明校验等;不能只按 OAuth2 换到访问令牌就认定身份验证完成。
- CAS / SAML:当前检查范围内未发现现成完整接入实现,需要开发对应协议适配。
- 自定义票据:按客户提供的服务端验票接口和安全规则适配。
举例:客户统一门户进入办公平台
假设客户已有统一认证 https://login.example.com,办公平台部署在 https://oa.example.com,员工“张三”在认证系统中的稳定用户标识为 employee-10086。
- 在客户认证服务注册办公平台应用,获取应用编号和服务端密钥,登记约定的回调地址。
- 在平台侧实现或配置对应认证渠道。自建认证渠道的回调路径由实际实现确定,不应把示例地址当成现成接口。
- 将外部用户
employee-10086绑定到平台中张三的本地账号,并明确所属租户、公司和部门。 - 张三在门户登录后打开办公平台,平台通过授权回调确认身份,进入张三有权限访问的办公页面。
当前管理端第三方登录要求存在本地账号绑定,未绑定会拒绝登录。 若希望首次登录自动开户,需要增加开户规则;姓名不适合作为唯一匹配条件,建议使用认证源和稳定用户标识,并明确租户边界。
人员新增、调岗、离职是否同步,采用定时同步还是事件通知,属于另一个对接范围。外部身份认证通过后,菜单、角色和数据权限仍需在平台侧落实。
三、方案二:平台作为认证服务
已有能力
平台已有 OAuth2 授权码登录链路,以及客户端管理、授权页面、令牌刷新、令牌校验、令牌撤销和用户信息接口。对外应用推荐由应用后端换取令牌,客户端密钥保存在服务端。
配置和接口示例
假设接入“项目协作系统”,在平台 OAuth2 客户端管理中登记:
- 客户端编号:
project-portal。 - 客户端密钥:由实施人员生成并放到项目系统后端配置中。
- 授权类型:
authorization_code;需要持续会话时同时配置refresh_token。 - 授权范围:只读取身份时使用
user.read。 - 回调地址:
https://project.example.com/sso/callback。 - 自动授权范围:由客户决定,可信内部应用可按需配置
user.read,否则由用户确认。
平台前端若使用 history 路由,浏览器授权入口示例为:
https://oa.example.com/auth/sso-login
?response_type=code
&client_id=project-portal
&redirect_uri=https%3A%2F%2Fproject.example.com%2Fsso%2Fcallback
&scope=user.read
&state=<本次请求的随机值>上面为便于阅读分行显示,实际请求应拼成一个 URL。若平台部署在 /web/ 且使用 hash 路由,入口为 https://oa.example.com/web/#/auth/sso-login?...,应与实际前端部署一致。
应用收到回调后核对 state,再由后端发起换票请求:
POST /admin-api/system/oauth2/token
Authorization: Basic <base64(client_id:client_secret)>
Content-Type: application/x-www-form-urlencoded
tenant-id: <本次用户所属租户编号>
grant_type=authorization_code&code=<授权码>&redirect_uri=<URL编码后的回调地址>&state=<原始state>接口默认前缀是 /admin-api,如部署更改了前缀,以实际配置为准。租户环境中须保证授权与换票处于同一租户上下文,租户选择应与可信配置和实际身份核对,不能仅信任任意传入的编号。
成功响应结构示意如下,过期秒数以客户端配置为准:
{
"code": 0,
"data": {
"access_token": "<访问令牌>",
"refresh_token": "<刷新令牌>",
"token_type": "bearer",
"expires_in": 1800,
"scope": "user.read"
},
"msg": ""
}随后携带 Authorization: Bearer <访问令牌> 调用 GET /admin-api/system/oauth2/user/get 获取用户信息,该接口要求 user.read。可用接口还包括:
- 刷新:
POST /admin-api/system/oauth2/token,使用grant_type=refresh_token和refresh_token参数。 - 校验:
POST /admin-api/system/oauth2/check-token,提交token参数。 - 撤销:
DELETE /admin-api/system/oauth2/token?token=<访问令牌>。
上述刷新、校验和撤销接口需要客户端 Basic 凭据,由后端调用。授权码是一次性凭据,换票所用的客户端、回调地址和 state 应与发起授权时一致。
协议兼容边界
当前提供的是平台现有 OAuth2 接口,响应采用 code/data/msg 包装;访问令牌是服务端保存的随机字符串,接入方不能按 JWT 自行解码验证。
当前检查范围内未发现完整 OIDC 服务所需的发现接口、id_token、JWKS,以及 PKCE 参数处理。若第三方产品只支持标准 OIDC 配置,或要求 PKCE、CAS、SAML,应先做兼容评估,增加适配或认证网关后再接入,不能承诺直接填写地址即可使用。
四、实际案例:智能体接入一体化平台
AgentOS 是 OAuth2 接入应用,RuoYi Office 一体化平台是认证服务。 所谓“智能体单点到一体化平台”,在当前实现中,是智能体跳转到平台完成身份认证,再回到智能体工作台。
两种使用入口
- 从平台进入:员工已在一体化平台登录,点击“智能体工作台”。AgentOS 发起授权,符合自动授权配置或已有批准记录时直接回到智能体,无需再次输入账号密码。
- 直接访问智能体:员工打开智能体地址,AgentOS 跳到平台认证;若平台尚未登录,先完成登录,再授权返回智能体。
是否显示授权确认页取决于授权范围、自动授权配置和已有批准记录。单点登录并不意味着每次都没有页面跳转。
配置示例
假设平台 Web 部署在 https://office.example.com/web/,智能体部署在 https://office.example.com/ai/:
- 平台 OAuth2 客户端编号使用
agentos,回调登记为https://office.example.com/ai/sso-callback。 - 智能体前端
VITE_MAINLINE_WEB_URL指向平台 Web 地址;平台采用 hash 路由时,VITE_MAINLINE_ROUTER_HISTORY配为hash。 - 智能体后端
AGENTOS_MAINLINE_URL指向可访问的平台后端基础地址,AGENTOS_CLIENT_ID=agentos,AGENTOS_CLIENT_SECRET与平台客户端配置一致。 - 当前智能体前端申请
user.read user.write,客户端允许范围须与当前版本匹配;其他只读应用不必照搬写权限。 - 智能体回调根据当前访问地址及前端基础路径生成,部署在
/ai/时应为/ai/sso-callback。若域名或部署路径改变,客户端回调配置也要同步调整。
这个案例的三个关键点
- 密钥保存在智能体后端:浏览器只负责授权跳转和回调,换票与刷新由后端完成。
- 使用平台签发的令牌:当前 AgentOS 换取的是平台令牌,调用平台业务接口时透传员工身份,最终受平台接口权限和数据权限控制。
- 租户与会话分别处理:当前实现将租户编号和随机值放入
state并校验回调,换票时透传租户头;退出智能体时撤销智能体这张令牌,不会自动退出平台原有会话。
部署细节见智能体完整部署手册和本地启动与调试。该案例说明现有应用如何接入,不代表所有第三方应用都应采用与智能体相同的令牌透传方式。
五、上线前需要客户提供什么
实施前先确定以下信息,避免只讨论“支持单点登录吗”而遗漏实际工作量:
- 认证方向和协议:谁提供认证;OAuth2、OIDC、CAS、SAML 还是自定义票据;提供对应接口文档和测试环境。
- 应用与地址:应用编号、服务端密钥的配置方式、认证入口、接口地址、生产和测试回调地址,以及前端部署路径和路由模式。
- 用户映射:稳定身份标识、本地账号关联、租户归属、首次登录未建账号时如何处理。
- 组织和权限:是否同步人员、部门、岗位;谁维护角色;离职、停用、调岗如何生效。
- 会话策略:令牌有效期、刷新策略、自动授权范围、退出当前应用还是要求全系统统一退出。
- 终端范围:PC 浏览器、移动 H5、原生 App 是否都需要接入;各终端回调和登录方式分别验证。
六、联调与上线验收
- [ ] 未登录时能完成认证并回到原目标页面;已登录时按认证策略免重复输入密码。
- [ ]
state不匹配的回调被拒绝,授权码重复使用失败,回调地址及路由模式配置正确。 - [ ] 认证服务返回的稳定身份正确映射到本地账号;未绑定、账号不存在和账号停用有明确处理结果。
- [ ] 多租户用户进入正确租户,业务查询和操作符合角色及数据权限。
- [ ] 用户拒绝授权、认证服务不可用、授权码过期时有提示,不发生循环跳转。
- [ ] 令牌到期、刷新和撤销按约定生效;退出当前应用与统一退出按约定分别验收。
- [ ] 客户端密钥只保存在服务端,生产使用 HTTPS,回调配置限定为应用实际需要的地址范围。
- [ ] 需要账号或组织同步时,新增、调岗、离职分别验证;这些结果单独记录。
- [ ] 智能体场景额外验证
/ai/sso-callback、平台菜单入口,以及普通员工与管理员的业务权限。
七、常见问题
有 OAuth2,是不是就兼容所有单点登录产品?
不是。需要核对协议和接口约定,尤其是 OIDC、PKCE、响应结构及令牌校验方式。平台现有 OAuth2 授权码能力可作为接入基础,是否无需开发取决于对方产品是否支持这些约定。
接入统一认证后,还需要平台账号吗?
需要本地身份承载角色、数据权限和业务关系。当前第三方登录要求本地账号绑定;自动开户和组织同步需另行实现或约定。
登出平台,其他系统会一起退出吗?
当前不能按此承诺。撤销一张令牌与结束所有应用会话是不同动作,若需要统一退出,应增加跨系统会话联动,并验证各应用是否真正退出。
接入方拿到身份,就能调用所有业务功能吗?
不能。业务接口仍受用户角色和数据权限限制;对外开放哪些 API 及如何限制应用授权范围,需要逐项核对,不能把 user.read 理解为所有业务接口的隔离规则。
进一步的接口实现与授权机制见OAuth2 开发指南。
