基础授权(Aegis.Core.Authorization)
当你需要在 Aegis 中统一处理受保护接口、访问 CurrentUser、执行 ApiAuthorize 校验,或者为 ESS 这类具体权限实现提供授权基础层时,可以接入 Aegis.Core.Authorization。本文聚焦它在 3.x 下的接入方式、职责边界和常见使用模式。
组件概览
| 字段 | 说明 |
|---|---|
| 组件名称 | 基础授权 |
| 真实类库 | Aegis.Core.Authorization |
| 父级组件 | Aegis.Core.Authentication |
| 子级扩展 | Aegis.Authorization.ESS 或自定义 IAuthorizationManager 实现 |
| 组件定位 | 提供授权过滤器、资源权限缓存、ApiAuthorize 特性和授权上下文抽象 |
| 引入方式 | Component.deps.json |
| 组件声明 | Authorization |
| 核心能力 | ApiAuthorize、权限缓存、资源权限抽象、当前用户扩展字典 |
| 是否可扩展 | 是 |
| 目标框架 | net8.0 |
| 注册入口 | src/Core/Aegis.Core.Authorization/ServiceCollectionExtensions.cs |
基础授权依赖基础认证先建立当前用户上下文,因此不能单独使用。它负责“怎么拦、拦什么、权限如何缓存”,但并不内置具体的权限来源。要真正按资源列表做授权判断,还需要再配一个 IAuthorizationManager 的具体实现,例如 ESS。
如何引入
NuGet 包
| 角色 | NuGet 包 | 是否必需 | 说明 |
|---|---|---|---|
| 认证基础层 | Aegis.Core.Authentication | 是 | 基础授权依赖当前用户上下文 |
| 授权基础层 | Aegis.Core.Authorization | 是 | 提供授权过滤和资源权限缓存 |
| 具体实现 | Aegis.Authorization.ESS 或自定义实现 | 按需 | 提供真正的权限来源 |
Component.deps.json
基础授权既有服务注册,也有中间件加载,并且它显式依赖 Authentication。推荐顺序如下:
{
"Components": {
"Services": [
"Authentication",
"Authorization",
"EssAuthorize"
],
"Middlewares": [
"Authentication",
"Authorization",
"EssAuthorize"
]
}
}
其中:
Authentication:建立当前用户和认证链路Authorization:加载授权服务和UseAuthorization()EssAuthorize:提供真实的权限来源与客凭校验能力
如果你只接入 Authorization,却没有 Authentication,组件顺序校验会直接失败。
配置说明
基础授权最关键的配置是总开关:
| 节点 | 类型 | 是否必填 | 说明 | 常见取值 / 示例 |
|---|---|---|---|---|
Auth:EnableAuthorization | bool | 建议是 | 是否启用授权校验;关闭后 ApiAuthorize 会直接放行 | true |
最小配置示例:
{
"Auth": {
"EnableAuthorization": true
}
}
快速使用
第一步:按顺序接入认证和授权
确保你已经:
- 安装
Aegis.Core.Authentication - 安装
Aegis.Core.Authorization - 在
Component.deps.json中先写Authentication,再写Authorization
第二步:在接口上使用 ApiAuthorize
using Aegis.Core.Authentication;
using Aegis.Core.Authorization.Filters;
using Aegis.Core.Infrastructure.Controller;
using Microsoft.AspNetCore.Authorization;
[ApiAuthorize]
public class OrdersController : ApiControllerBase
{
[HttpGet("me")]
public object Me()
{
return CurrentUser.Value;
}
[AllowAnonymous]
[HttpGet("ping")]
public string Ping()
{
return "ok";
}
}
第三步:确认授权链路生效
你应该能观察到这些结果:
- 未带 Token 访问受保护接口时返回
401 - 标记了
AllowAnonymous的接口不会被ApiAuthorize拦截 - 如果同时注册了具体授权实现,没有权限访问时会返回
403
具体使用详情
ApiAuthorize 的行为边界
ApiAuthorize 的处理顺序大致如下:
- 先检查
Auth:EnableAuthorization - 再检查当前接口是否标记了
AllowAnonymous - 然后确认
CurrentUser.Value是否存在 - 最后根据
IAuthorizationManager返回的资源权限执行访问控制
这意味着:
- 关闭授权开关后,
ApiAuthorize不再拦截 AllowAnonymous会跳过授权检查- 没有具体授权实现时,基础授权只能完成“受保护接口拦截”,不能完成真正的资源权限判定
资源权限缓存
基础授权默认使用 DefaultResourcePermissionManager,把资源权限缓存到内存中,缓存时间是 20 分钟。它的作用是:
- 减少重复查询远端权限服务
- 让同一个 Token 在一段时间内复用已取回的权限
如果你需要跨实例共享权限缓存,应该替换 IResourcePermissionManager 的实现。
当前用户扩展字典
基础授权还提供了面向 CustomUser 的扩展字典,可用于在一次登录周期内暂存业务数据:
using Aegis.Core.Authorization.Extensions;
CurrentUser.Value.Set("tenant", "demo");
var tenant = CurrentUser.Value.Get<string>("tenant");
这适合存储:
- 当前租户
- 当前组织
- 已经解析好的轻量业务上下文
如何扩展
自定义权限来源
如果你需要对接自己的权限中心,可以实现 IAuthorizationManager,负责返回资源权限列表。基础授权会继续负责:
- 在请求链路上触发授权检查
- 缓存权限结果
- 结合
ApiAuthorize完成接口拦截
自定义权限缓存
默认的 DefaultResourcePermissionManager 使用内存缓存。如果你的场景有下面这些需求,建议替换它:
- 多实例共享权限缓存
- 更长或更短的缓存策略
- 需要按租户、系统或业务域拆分权限缓存
自定义资源描述
如果你需要把接口、按钮、菜单或其他资源模型统一管理,也可以围绕下面这些抽象继续扩展:
IResourceManagerIResourcePermissionManagerResourceResourcePermission
常见问题指南
为什么加了 Authorization 以后,接口还是没有真正按权限拦截?
因为基础授权只负责授权框架,不负责权限来源。要实现真正的资源权限校验,还需要接入 Aegis.Authorization.ESS 或你自己的 IAuthorizationManager。
为什么 ApiAuthorize 没有拦住某个接口?
优先检查:
Auth:EnableAuthorization是否为true- 当前接口或控制器是否标记了
AllowAnonymous Authorization是否已经加入Middlewares- 是否已经注册了具体授权实现
为什么 Authentication 和 Authorization 的顺序不能反过来?
因为授权判断依赖 CurrentUser。只有认证先把用户写入上下文,授权层才能继续判断是否允许访问。