跳到主要内容
版本:3.0.0

JWT 认证(Aegis.Authorization.Jwt)

当你不想依赖外部认证中心,而是希望在应用内生成 Bearer Token、通过登录接口发放 Token 并在后续请求里复用时,可以接入 Aegis.Authorization.Jwt。下面说明当前版本下它的实际接法、能力边界和已知约束。

组件概览

字段说明
组件名称JWT 认证
真实类库Aegis.Authorization.Jwt
父级组件Aegis.Core.Authentication
子级扩展Aegis.Authorization.RedisUserManager
组件定位提供 IAuthenticationManager 的 JWT 实现,用于本地发放与校验登录 Token
引入方式Component.deps.json
组件声明JwtAuthorize
核心能力登录发放 Token、会话存储、过期检查
是否可扩展
目标框架net8.0
注册入口src/Authorization/Aegis.Authorization.Jwt/ServiceCollectionExtensions.cs

这个组件更适合内部系统、单体服务或受控环境里的本地 Token 场景。当前版本的实现并不是纯粹的“无状态 JWT 网关”,它仍然依赖 IUserManager 保存登录会话,因此部署形态会直接影响 Token 是否跨实例可用。

如何引入

NuGet 包

角色NuGet 包是否必需说明
基础层Aegis.Core.Authentication提供认证中间件和当前用户上下文
具体实现Aegis.Authorization.Jwt提供 JWT 登录与 Token 校验实现
会话扩展Aegis.Authorization.RedisUserManager按需多实例时用于共享会话

Component.deps.json

{
"Components": {
"Services": [
"Authentication",
"JwtAuthorize"
],
"Middlewares": [
"Authentication"
]
}
}

配置说明

JWT 认证当前公开的配置项如下:

节点类型是否必填说明常见取值 / 示例
Auth:EnableAuthenticationbool建议是是否启用认证校验true
JwtAuthorize:IssuerstringToken 发行者Aegis
JwtAuthorize:AudiencestringToken 受众Aegis.Api

最小配置示例:

{
"Auth": {
"EnableAuthentication": true
},
"JwtAuthorize": {
"Issuer": "Aegis",
"Audience": "Aegis.Api"
}
}

补充说明:

  • 当前版本没有独立的固定密钥配置节点。
  • 登录时传入的 LoginInfo.Password 会参与 Token 生成,因此登录接口参数设计需要你自己控制好。

快速使用

第一步:启用基础认证和 JWT 认证

确保你已经:

  • 安装 Aegis.Core.Authentication
  • 安装 Aegis.Authorization.Jwt
  • Component.deps.json 中加入 AuthenticationJwtAuthorize
  • 在配置中提供 IssuerAudience

第二步:调用登录接口获取 Token

JWT 认证接入后,可以直接使用基础认证提供的登录接口:

POST /api/Auth/Login

示例请求体:

{
"userIdentity": "demo-user",
"password": "demo-secret",
"expiresMinutes": 30,
"userModel": {
"name": "Demo"
}
}

第三步:访问受保护接口

拿到登录接口返回的 Token 后,在请求头中带上:

Authorization: Bearer {token}

如果接入正常,你应该能看到:

  • 登录接口返回 Token
  • 受保护接口可以读取 CurrentUser.Value
  • Token 过期后,会从会话存储中被移除

具体使用详情

登录与会话关系

当前 JwtAuthenticationManager 的工作方式是:

  1. 登录时根据 IssuerAudienceLoginInfo.Password 生成 Token
  2. 把生成的 Token 和用户信息写入 IUserManager
  3. 后续请求用 Token 到 IUserManager 查回当前用户

这意味着:

  • Token 不只是签名串,也同时充当会话索引
  • 如果会话存储中没有这个 Token,当前请求就不会被识别为已登录

过期处理

当前实现会在 CheckToken(...) 时检查会话过期时间:

  • 未过期:继续返回当前用户
  • 已过期:删除用户会话,并把当前登录视为无效

使用边界

这个实现更适合:

  • 本地开发和功能验证
  • 单实例内部系统
  • 需要快速接入 Token 登录,但暂时不依赖外部认证中心的场景

如果你希望 Token 真正独立于会话存储长期有效,当前版本还不适合作为最终的无状态认证方案。

如何扩展

替换会话存储

如果你希望多个实例共享登录状态,可以引入 Redis 用户会话:

services.AddRedisSource<AegisRedisSource>(ConfigManager.Get<RedisOptions>("Redis"));
services.AddRedisUserManager<AegisRedisSource>();

自定义认证实现

如果你需要更严格的 JWT 签名校验、刷新机制或统一密钥策略,建议:

  • 自己实现 IAuthenticationManager
  • 继续复用基础认证的中间件和 CurrentUser

常见问题指南

为什么服务一重启,JWT 就失效了?

因为当前实现会把登录态写入 IUserManager。如果仍在使用默认内存会话,应用重启后数据会全部丢失。

为什么调用 /api/Auth/Logout 会报错?

因为当前版本的 JwtAuthenticationManager.Logout(...) 还没有实现,不适合把它当作完整的登出方案直接使用。

为什么我只配了 IssuerAudience,没有看到独立密钥配置?

因为当前版本公开的 JwtOption 只有这两个字段。登录时用于生成 Token 的密钥并不来自独立配置节点,而是来自登录参数本身。