基础认证(Aegis.Core.Authentication)
当你需要在 Aegis Web API 中启用 Bearer Token 认证、在请求链路里读取当前用户、为 SSO / JWT / ESS 这类具体认证方案提供统一入口时,可以接入 Aegis.Core.Authentication。本文按 Aegis 3.x / .NET 8 口径说明当前组件的真实作用、接入方式和使用边界。
组件概览
| 字段 | 说明 |
|---|---|
| 组件名称 | 基础认证 |
| 真实类库 | Aegis.Core.Authentication |
| 组件定位 | 提供认证管线、Token 处理中间件、CurrentUser 上下文和 IUserManager / IAuthenticationManager 抽象 |
| 子级扩展 | Aegis.Authorization.SSO、Aegis.Authorization.Jwt、Aegis.Authorization.ESS、Aegis.Authorization.RedisUserManager |
| 引入方式 | Component.deps.json,可叠加手动替换 IUserManager |
| 组件声明 | Authentication |
| 核心能力 | Bearer 认证注册、Token 读取、当前用户上下文、默认内存会话管理 |
| 是否可扩展 | 是 |
| 目标框架 | net8.0 |
| 注册入口 | src/Core/Aegis.Core.Authentication/ServiceCollectionExtensions.cs |
这个组件负责把“认证这件事”接入 Aegis 的请求链路,但它本身不是具体登录方案。只接入 Aegis.Core.Authentication,并不代表系统已经具备 SSO、JWT 或 ESS 的登录能力。要让 /api/Auth/Login、Token 校验和 CurrentUser.Value 真正工作,还需要再接入一个具体实现组件。
如何引入
NuGet 包
| 角色 | NuGet 包 | 是否必需 | 说明 |
|---|---|---|---|
| 基础层 | Aegis.Core.Authentication | 是 | 提供认证管线和当前用户上下文 |
| 具体实现 | Aegis.Authorization.SSO / Aegis.Authorization.Jwt / Aegis.Authorization.ESS | 至少选一个 | 提供 IAuthenticationManager 的具体实现 |
Component.deps.json
基础认证既有服务注册,也有中间件加载,因此 Authentication 需要同时出现在 Services 和 Middlewares 中。下面示例使用 JWT 作为最小落地方案:
{
"Components": {
"Services": [
"Authentication",
"JwtAuthorize"
],
"Middlewares": [
"Authentication"
]
}
}
其中:
Authentication:注册认证服务、默认的IUserManager和 Token 处理中间件。JwtAuthorize:为基础认证补上具体的登录和 Token 校验实现。
如果你只写了 Authentication,却没有引入任何具体实现,认证链路虽然会建立,但登录和 Token 校验无法完整工作。
配置说明
基础认证当前最直接依赖的是 Auth:EnableAuthentication 开关:
| 节点 | 类型 | 是否必填 | 说明 | 常见取值 / 示例 |
|---|---|---|---|---|
Auth:EnableAuthentication | bool | 建议是 | 是否启用认证校验;关闭后 TokenHandler 会直接放行请求 | true |
最小配置示例:
{
"Auth": {
"EnableAuthentication": true
}
}
手动注入与例外情况
基础认证默认会注册内存版 DefaultUserManager。如果你需要分布式会话,建议在宿主项目中替换 IUserManager 的实现,例如:
services.AddRedisSource<AegisRedisSource>(ConfigManager.Get<RedisOptions>("Redis"));
services.AddRedisUserManager<AegisRedisSource>();
这种方式适合:
- 多实例部署
- 登录状态需要跨节点共享
- 不希望应用重启后丢失会话
快速使用
基础认证本身需要配合一种具体实现才能跑通。下面用 JWT 给出一条最短路径。
第一步:完成依赖和配置
确保你已经:
- 安装
Aegis.Core.Authentication - 安装一种具体实现组件,例如
Aegis.Authorization.Jwt - 在
Component.deps.json中加入Authentication - 在配置中启用
Auth:EnableAuthentication
第二步:调用登录接口
当系统中已经注册 IAuthenticationManager 后,基础认证会暴露默认认证接口:
POST /api/Auth/LoginPOST /api/Auth/Logout
例如:
{
"userIdentity": "demo-user",
"password": "demo-secret",
"expiresMinutes": 30,
"userModel": {
"name": "Demo"
}
}
第三步:在受保护接口里读取当前用户
using Aegis.Core.Authentication;
using Aegis.Core.Infrastructure.Controller;
using Microsoft.AspNetCore.Mvc;
public class ProfileController : ApiControllerBase
{
[HttpGet("current-user")]
public object GetCurrentUser()
{
return CurrentUser.Value;
}
}
如果认证链路已经生效,你应该能看到这些结果:
- 登录接口返回 Token
- 后续请求携带
Authorization: Bearer {token}后,CurrentUser.Value可以读取到当前用户 - 未标记
AllowAnonymous的接口在缺少 Token 时会返回401
具体使用详情
Token 处理链路
基础认证在中间件阶段会加载 TokenHandler,它负责:
- 检查
Auth:EnableAuthentication - 读取
Authorization请求头 - 调用当前注册的
IAuthenticationManager.CheckToken(...) - 把用户写入
CurrentUser.Value
如果当前接口没有标记 AllowAnonymous,又缺少 Authorization 头,系统会直接返回 401。
当前用户上下文
认证通过后,可以通过 CurrentUser.Value 访问当前用户。当前用户模型 CustomUser 里常用的字段包括:
UserIdentity:用户唯一标识Token:当前 Bearer TokenRefreshToken:刷新 TokenExpireAt:过期时间UserInfo:具体认证实现写入的用户信息ExtendInfo:扩展返回信息
默认认证接口
基础认证自带 AuthController,默认路由是:
POST /api/Auth/LoginPOST /api/Auth/Logout
这两个接口本质上都委托给当前注入的 IAuthenticationManager。因此:
- 是否支持登录,取决于你注册了哪个具体实现
- 返回的用户结构和 Token 规则,也由具体实现决定
默认会话管理
如果你没有替换 IUserManager,系统会使用 DefaultUserManager,它的特点是:
- 数据保存在内存中
- 适合单实例和本地调试
- 应用重启后会话丢失
- 多实例之间不共享登录状态
如何扩展
替换用户会话管理
最常见的扩展方式是替换默认的 IUserManager。例如:
- 单机调试:继续使用默认内存实现
- 多实例部署:改用
Aegis.Authorization.RedisUserManager - ESS 场景:也可以使用
EssRedisUserManager<T>
自定义认证实现
如果现有的 SSO、JWT、ESS 都不适合你的场景,可以自己实现:
IAuthenticationManager:负责登录、登出和 Token 校验IUserManager:负责用户会话的存储与读取
接入思路通常是:
- 让自定义组件注册自己的
IAuthenticationManager - 继续复用
Authentication的中间件和CurrentUser上下文 - 按需替换用户会话存储
常见问题指南
为什么只接了 Authentication,登录接口还是不能用?
因为基础认证只提供认证管线,不提供具体登录逻辑。要让 /api/Auth/Login 真正工作,还必须注册一个具体实现,例如 SSO、JWT 或 ESS。
为什么接口已经加了 Token,但 CurrentUser.Value 还是空?
优先检查这些项:
Auth:EnableAuthentication是否为trueAuthentication是否已经加入Middlewares- 是否已经注册了
IAuthenticationManager - 请求头是否使用了
Authorization: Bearer {token}格式
为什么应用一重启,用户就全部掉线了?
因为默认的 DefaultUserManager 是内存实现。需要跨实例、跨重启保留会话时,应改用 Redis 或其他持久化会话实现。