如何仅在带有[Authorize]特性的端点上条件使用中间件
你现在的问题是判断逻辑方向错了——你当前检查的是用户是否已登录,但真正需要判断的是当前请求的端点是否要求授权(也就是有没有[Authorize]特性),同时还要排除那些标记了[AllowAnonymous]的特殊情况。
具体调整步骤:
- 先确保你的中间件配置放在
app.UseRouting()之后,因为只有路由匹配完成后,HttpContext里才会有Endpoint对象(这是获取端点元数据的前提)。 - 修改
UseWhen的判断逻辑,从Endpoint的元数据中检查授权相关特性:
app.UseWhen(context => { // 获取当前请求匹配到的端点信息 var endpoint = context.GetEndpoint(); if (endpoint == null) return false; // 检查端点是否包含[Authorize]特性(包括继承自控制器的特性) var requiresAuthorization = endpoint.Metadata.GetMetadata<AuthorizeAttribute>() != null; // 排除标记了[AllowAnonymous]的端点(即使父控制器有[Authorize]也不触发) var hasExemption = endpoint.Metadata.GetMetadata<AllowAnonymousAttribute>() != null; // 只有当端点需要授权且无豁免时,才触发中间件 return requiresAuthorization && !hasExemption; }, appBuilder => { appBuilder.UseAutomaticallyRefreshTokenMiddleware(); });
为什么这样有效?
context.GetEndpoint()能拿到当前请求对应的控制器/Action端点信息,这是判断的核心依据Metadata.GetMetadata<T>()可以检索该端点上所有的特性,包括从父控制器继承来的[Authorize]- 加入
AllowAnonymous的判断是为了覆盖“控制器加了授权,但单个Action豁免”的场景,保证逻辑严谨性
调整后,你的中间件就只会在需要授权且没有豁免的端点上触发,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Lee
相关产品推荐
相关产品推荐

