C# 自定义授权要求方法 C#如何创建IAuthorizationRequirement和Handler

发布时间 - 2026-02-02 00:00:00    点击率:
IAuthorizationRequirement是仅用于类型标记的空接口,要求不可变且通过构造函数传参;Handler必须继承AuthorizationHandler并重写HandleRequirementAsync,注册需为Scoped且策略名、类型、参数须完全匹配。

IAuthorizationRequirement 是个空接口,只起标记作用

它本身不带任何逻辑,纯粹用于类型区分——比如你定义 MinimumAgeRequirementHasPermissionRequirement,都继承自它,目的是让 Handler 能通过泛型匹配到对应处理逻辑。不要试图在里面加属性或方法来“控制授

权流程”,那是 Handler 的事。

常见错误:给 Requirement 加 public bool IsSatisfied { get; set; } 这类运行时状态字段。它会被反复实例化,状态无法保持,也违背了 Requirement 应该是不可变(immutable)设计原则。

正确做法是把必要参数全塞进构造函数,并设为只读:

public class MinimumAgeRequirement : IAuthorizationRequirement
{
    public int MinimumAge { get; }
    public MinimumAgeRequirement(int minimumAge) => MinimumAge = minimumAge;
}

Handler 必须继承 AuthorizationHandler 且重写 HandleRequirementAsync

这是真正干活的地方。ASP.NET Core 在授权时会查找所有注册的 AuthorizationHandler,并把当前 AuthorizationHandlerContext 和匹配的 Requirement 实例传进来。你得在这个方法里决定调用 context.Succeed(requirement) 还是 context.Fail()

关键点:

  • 必须用 protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MinimumAgeRequirement requirement) 签名,泛型参数 T 必须和你注册的 Requirement 类型一致
  • 不能漏掉 context.Fail() —— 如果条件不满足又没调用 Fail,授权会“静默通过”(因为默认不失败)
  • 不要在 Handler 里直接 throw 异常,授权失败走 Fail(),异常留给中间件层处理
  • 如果需要访问用户信息,从 context.User 拿;要读 Claim,别手动遍历,用 context.User.FindFirst("age")?.Valuecontext.User.HasClaim()

注册 Requirement 和 Handler 要配对,且顺序影响行为

Program.cs(.NET 6+)中注册时,先用 AddAuthorization 添加策略,再用 AddScoped 注册 Handler。Requirement 不需要单独注册,但策略里要用到它:

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("MinimumAge18", policy =>
        policy.Requirements.Add(new MinimumAgeRequirement(18)));
});

builder.Services.AddScoped();

注意:

  • 多个 Handler 可以处理同一个 Requirement,它们都会被执行(除非某个调用了 context.Succeed() 后你主动 return
  • 如果一个策略绑了多个 Requirement,所有对应 Handler 都必须成功,策略才算通过
  • Handler 注册必须是 Scoped(不是 Singleton),因为 AuthorizationHandlerContext 是每次请求新建的

调试时最常卡在 Handler 没被触发

现象:加了断点但完全不进 HandleRequirementAsync,策略始终失败。大概率是下面几个原因:

  • Handler 类型没注册,或者注册成了 AddSingleton 导致依赖注入失败
  • 策略名拼错,比如控制器上写了 [Authorize(Policy = "MinAge18")],但注册的是 "MinimumAge18"
  • Requirement 构造时传参出错,比如 new MinimumAgeRequirement(null) 导致构造函数抛异常,Handler 根本没创建出来
  • .NET 版本差异:.NET 5+ 要求 Handler 必须实现 IAuthorizationHandler 接口(虽然继承 AuthorizationHandler 已隐式实现,但某些反射场景会校验)

建议加一行日志在 Handler 构造函数里,确认它是否被创建;再在 HandleRequirementAsync 开头打日志,看是否进入。比断点更可靠。

Requirement 和 Handler 的耦合其实很轻,但注册链上任意一环断开,整个授权就静默失效——这点最容易被忽略。


# ai  # c#  # .net  # 中间件  # NULL  # 构造函数  # throw  # bool  # 继承  # 接口  # public  # protected  # 泛型  # 多个  # 重写  # 的是  # 这是  # 几个  # 是个  # 成了  # 在这个  # 那是  # 不需要 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: CSS3怎么给轮播图加过渡动画_transition加transform实现【技巧】  HTML5段落标签p和br怎么选_文本排版常用标签对比【解答】  HTML5空格和nbsp有啥关系_nbsp的作用及使用场景【说明】  Python3.6正式版新特性预览  东莞市网站制作公司有哪些,东莞找工作用什么网站好?  Laravel Facade的原理是什么_深入理解Laravel门面及其工作机制  b2c电商网站制作流程,b2c水平综合的电商平台?  Laravel如何升级到最新版本?(升级指南和步骤)  如何快速打造个性化非模板自助建站?  怎么用AI帮你为初创公司进行市场定位分析?  Win11怎么关闭透明效果_Windows11辅助功能视觉效果设置  免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?  作用域操作符会触发自动加载吗_php类自动加载机制与::调用【教程】  C++时间戳转换成日期时间的步骤和示例代码  EditPlus中的正则表达式实战(6)  Laravel怎么实现软删除SoftDeletes_Laravel模型回收站功能与数据恢复【步骤】  Laravel怎么创建自己的包(Package)_Laravel扩展包开发入门到发布  Chrome浏览器标签页分组怎么用_谷歌浏览器整理标签页技巧【效率】  Laravel如何使用查询构建器?(Query Builder高级用法)  Win11怎么关闭资讯和兴趣_Windows11任务栏设置隐藏小组件  网页制作模板网站推荐,网页设计海报之类的素材哪里好?  如何生成腾讯云建站专用兑换码?  Edge浏览器如何截图和滚动截图_微软Edge网页捕获功能使用教程【技巧】  弹幕视频网站制作教程下载,弹幕视频网站是什么意思?  Python文件操作最佳实践_稳定性说明【指导】  如何登录建站主机?访问步骤全解析  Laravel怎么生成二维码图片_Laravel集成Simple-QrCode扩展包与参数设置【实战】  北京网页设计制作网站有哪些,继续教育自动播放怎么设置?  打造顶配客厅影院,这份100寸电视推荐名单请查收  如何快速生成可下载的建站源码工具?  如何在阿里云通过域名搭建网站?  网站优化排名时,需要考虑哪些问题呢?  如何为不同团队 ID 动态生成多个非值班状态按钮  儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?  如何正确下载安装西数主机建站助手?  如何用AI一键生成爆款短视频文案?小红书AI文案写作指令【教程】  如何获取上海专业网站定制建站电话?  Laravel怎么处理异常_Laravel自定义异常处理与错误页面教程  Linux后台任务运行方法_nohup与&使用技巧【技巧】  Laravel如何使用Laravel Vite编译前端_Laravel10以上版本前端静态资源管理【教程】  高防网站服务器:DDoS防御与BGP线路的AI智能防护方案  SQL查询语句优化的实用方法总结  如何实现建站之星域名转发设置?  如何在新浪SAE免费搭建个人博客?  Win11怎么恢复误删照片_Win11数据恢复工具使用【推荐】  美食网站链接制作教程视频,哪个教做美食的网站比较专业点?  Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】  Laravel如何创建和注册中间件_Laravel中间件编写与应用流程  今日头条微视频如何找选题 今日头条微视频找选题技巧【指南】  详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)