ASP.NET Core 3.1授权中间件无法识别通过MVC约定添加的策略
问题根因分析
ASP.NET Core 3.0 引入端点路由后,AuthorizationMiddleware 执行优先级早于 MVC 过滤器管道,只会从端点元数据中读取 IAuthorizeData 类型的配置完成授权校验。你通过约定添加的是 AuthorizeFilter,属于 MVC 过滤器范畴,不会被纳入端点元数据,因此授权中间件读不到你配置的读写策略,直接触发了要求 ROLE_SITE_ADMIN/ROLE_SITE_BROWSER 角色的回退策略,导致 ROLE_API_READ 角色的用户校验失败。
解决方案
修改 DefaultApiAuthorizationConvention 类的实现,不再添加 AuthorizeFilter,改为向 Action 特性集合中添加 AuthorizeAttribute(该特性实现了 IAuthorizeData 接口,会自动被纳入端点元数据)。
修改后的约定代码
public class DefaultApiAuthorizationConvention : IActionModelConvention { private readonly string _apiReadPolicyName; private readonly string _apiWritePolicyName; public DefaultApiAuthorizationConvention(string apiReadPolicyName = Constants.POLICY_API_READ, string apiWritePolicyName = Constants.POLICY_API_WRITE) { _apiReadPolicyName = apiReadPolicyName; _apiWritePolicyName = apiWritePolicyName; } public void Apply(ActionModel action) { // 仅对API控制器生效 if (!action.Controller.Attributes.Any(a => a is ApiControllerAttribute)) return; // 可选判断:如果方法/控制器已经配置了授权或匿名特性,跳过约定逻辑,保证手动配置优先级更高 if (action.Attributes.Any(a => a is IAuthorizeData || a is IAllowAnonymous) || action.Controller.Attributes.Any(a => a is IAuthorizeData || a is IAllowAnonymous)) return; // POST/PUT/DELETE方法要求API Write策略,GET方法要求API Read策略 if (action.Attributes.Any(a => a is HttpPostAttribute || a is HttpPutAttribute || a is HttpDeleteAttribute)) { action.Attributes.Add(new AuthorizeAttribute(_apiWritePolicyName)); } else if (action.Attributes.Any(a => a is HttpGetAttribute)) { action.Attributes.Add(new AuthorizeAttribute(_apiReadPolicyName)); } } }
验证逻辑
修改完成后重启项目,调试时可以看到端点元数据中已经包含对应策略的 AuthorizeAttribute,AuthorizationMiddleware 读取到 IAuthorizeData 后会使用你配置的读写策略做校验,ROLE_API_READ 角色的用户访问GET接口即可正常通过。
内容的提问来源于stack exchange,提问作者holly_cheng
相关产品推荐
相关产品推荐

