SSO 认证(Aegis.Authorization.SSO)
当你的系统需要对接中心化 SSO 服务,通过远端用户中心校验 Token、补全用户信息,并把用户上下文写入 Aegis 请求链路时,可以接入 Aegis.Authorization.SSO。本文重点说明它在 3.x 下的定位、配置和与基础认证的组合方式。
组件概览
| 字段 | 说明 |
|---|---|
| 组件名称 | SSO 认证 |
| 真实类库 | Aegis.Authorization.SSO |
| 父级组件 | Aegis.Core.Authentication |
| 组件定位 | 对接远端 SSO,提供 IAuthenticationManager 的 SSO 实现 |
| 引入方式 | Component.deps.json |
| 组件声明 | SsoAuthorize |
| 核心能力 | SSO Token 校验、用户信息拉取、CurrentUser 写入、SsoUser() 快速访问 |
| 是否可扩展 | 有限 |
| 目标框架 | net8.0 |
| 注册入口 | src/Authorization/Aegis.Authorization.SSO/ServiceCollectionExtensions.cs |
这个组件只解决“认证”问题,不负责资源权限判定。也就是说,它适合做 SSO 登录态接入和当前用户获取;如果你还需要接口级权限控制,应再配合 Aegis.Core.Authorization 和具体的授权实现。
如何引入
NuGet 包
| 角色 | NuGet 包 | 是否必需 | 说明 |
|---|---|---|---|
| 基础层 | Aegis.Core.Authentication | 是 | 提供认证中间件和当前用户上下文 |
| 具体实现 | Aegis.Authorization.SSO | 是 | 提供 SSO 的认证实现 |
| 授权基础层 | Aegis.Core.Authorization | 按需 | 如果接口还需要授权控制,再额外引入 |
Component.deps.json
最小接入示例:
{
"Components": {
"Services": [
"Authentication",
"SsoAuthorize"
],
"Middlewares": [
"Authentication"
]
}
}
如果你还需要对接口做授权控制,可以继续追加:
{
"Components": {
"Services": [
"Authentication",
"Authorization",
"SsoAuthorize"
],
"Middlewares": [
"Authentication",
"Authorization"
]
}
}
配置说明
SSO 认证依赖 SSOAuthorize 配置段,同时建议打开认证开关:
| 节点 | 类型 | 是否必填 | 说明 | 常见取值 / 示例 |
|---|---|---|---|---|
Auth:EnableAuthentication | bool | 建议是 | 是否启用认证校验 | true |
SSOAuthorize:Host | string | 是 | SSO 服务地址 | http://sso.example.com/ |
SSOAuthorize:AppCode | string | 是 | 当前系统在 SSO 中的应用标识 | demo-app |
SSOAuthorize:UserCode | string | 是 | 调用 SSO 服务使用的账号 | sys |
SSOAuthorize:Password | string | 是 | 调用 SSO 服务使用的密码 | App1234. |
最小配置示例:
{
"Auth": {
"EnableAuthentication": true
},
"SSOAuthorize": {
"Host": "http://sso.example.com/",
"AppCode": "demo-app",
"UserCode": "sys",
"Password": "App1234."
}
}
快速使用
第一步:启用基础认证和 SSO 认证
确保你已经:
- 安装
Aegis.Core.Authentication - 安装
Aegis.Authorization.SSO - 在
Component.deps.json中加入Authentication和SsoAuthorize - 配好
SSOAuthorize节点
第二步:在业务接口里读取 SSO 用户
using Aegis.Authorization.SSO.Extensions;
using Aegis.Core.Authentication;
using Aegis.Core.Infrastructure.Controller;
public class ProfileController : ApiControllerBase
{
[HttpGet("profile")]
public object GetProfile()
{
var user = CurrentUser.Value;
var ssoUser = user.SsoUser();
return ssoUser;
}
}
第三步:确认认证结果
当请求头带上有效的 Authorization: Bearer {token} 后,你应该能观察到:
CurrentUser.Value不为空CurrentUser.Value.SsoUser()能直接拿到SSOUserModel- 不带 Token 访问受保护接口时会返回
401
具体使用详情
登录与 Token 校验
注册 SsoAuthorize 后,基础认证暴露的 /api/Auth/Login 和 /api/Auth/Logout 会委托给 SSO 的认证实现。除此之外,正常的 Bearer Token 请求也会按下面的方式工作:
- 认证中间件从请求头读取 Bearer Token
SsoAuthenticationManager先尝试从IUserManager读取用户会话- 如果本地会话不存在,再向 SSO 服务拉取用户信息
- 拉取成功后写入
CurrentUser.Value
获取 SSO 用户模型
当前包提供了 SsoUser() 扩展方法,可把 CurrentUser.Value.UserInfo 直接转成 SSOUserModel。这适合在控制器或服务层中快速访问:
- 用户姓名
- 用户编号
- 用户 ID
- 其他 SSO 返回的用户字段
和授权的关系
Aegis.Authorization.SSO 只注册 IAuthenticationManager,不注册 IAuthorizationManager。因此:
- 它能解决“你是谁”
- 但不解决“你能访问哪些接口”
如果你需要接口级权限控制,应额外接入 Aegis.Core.Authorization,并再提供具体授权实现。
如何扩展
替换会话存储
SSO 认证会依赖 IUserManager 存储用户会话。默认情况下,这个会话保存在内存中。对于多实例场景,更适合替换为 Redis 会话实现。
当前版本的扩展边界
当前版本更适合在以下位置做扩展:
- 用自定义
IUserManager替换会话存储 - 在业务层把
SSOUserModel转成自己的用户 DTO - 在外围系统里统一封装登录与回调流程
如果你需要的是资源权限、角色授权或客凭访问,这不属于当前组件的职责范围。
常见问题指南
为什么已经接了 SSO,ApiAuthorize 还是没有做权限拦截?
因为 SSO 组件只做认证,不做权限来源管理。要做资源权限控制,还要再接入授权基础层和具体授权实现。
为什么只加了 SsoAuthorize,系统还是启动失败?
因为 SsoAuthorize 依赖基础认证先完成服务注册。需要先接入 Authentication,再接入 SsoAuthorize。
为什么单机可用,多实例下登录状态不共享?
因为默认用户会话保存在内存中。需要跨节点共享会话时,应把 IUserManager 替换成 Redis 版本。