You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core IAuthorizationFilter获取顶层特性返回null

问题原因

获取控制器上的ModulePermissionAttribute始终返回null,核心原因是特性的扫描对象选错了:

  • 你当前调用的actionDescriptor.MethodInfo.GetCustomAttributes()仅会扫描当前Action方法、以及方法继承链上挂载的特性
  • 标注在控制器类顶层的ModulePermissionAttribute属于类级别特性,不在方法特性的扫描范围内,自然无法获取到返回null

除此之外你的现有代码还存在2个会导致运行/编译异常的问题:

  • ActionPermissionAttribute的属性写法存在递归死循环问题:原代码写的public Action action { get { return action; } }会在访问属性时反复调用自身,触发栈溢出,正确逻辑应该返回内部存储的_action私有字段
  • ModulePermissionAttribute缺少接收Module枚举类型的构造函数,你在控制器上写的[ModulePermission(Module.Product)]传入的是枚举值,和现有构造函数的string、Type参数不匹配,会直接编译失败

修复方案

1. 修正特性类的代码问题

先修复两个特性类的写法问题,补上枚举类型的构造函数重载,匹配控制器上的标注写法:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class ActionPermissionAttribute : Attribute
{
    private readonly Action _action;
    public Action Action => _action;

    public ActionPermissionAttribute(Action action = Action.Read)
    {
        _action = action;
    }
}

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ModulePermissionAttribute : Attribute
{
    private readonly string _module;
    public string Module => _module;

    // 原string参数构造
    public ModulePermissionAttribute(string module = "")
    {
        _module = string.IsNullOrEmpty(module) ? "Novalue" : module;
    }

    // 原Type参数构造
    public ModulePermissionAttribute(Type module)
    {
        _module = module.Name;
    }

    // 新增Module枚举构造重载,匹配控制器上的枚举传参
    public ModulePermissionAttribute(Module module)
    {
        _module = module.ToString();
    }
}

2. 从控制器类型信息上获取类级别特性

不要从MethodInfo对象上查找类级别的特性,改用ControllerActionDescriptor自带的ControllerTypeInfo属性,扫描控制器类上的标注:

public void OnAuthorization(AuthorizationFilterContext context)
{
    bool isAuthorized = false; // 替换为你的实际授权判断逻辑
    var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
    if (actionDescriptor == null)
    {
        context.Result = new ForbidResult();
        return;
    }

    // 从控制器类类型上获取ModulePermissionAttribute
    var moduleAttr = actionDescriptor.ControllerTypeInfo
        .GetCustomAttributes<ModulePermissionAttribute>(true)
        .FirstOrDefault();

    // 从Action方法上获取ActionPermissionAttribute,原有这部分逻辑是正确的
    var actionAttr = actionDescriptor.MethodInfo
        .GetCustomAttributes<ActionPermissionAttribute>(false)
        .FirstOrDefault();

    // 此处编写基于moduleAttr、actionAttr的权限校验逻辑
    if (moduleAttr == null || actionAttr == null)
    {
        // 未标注权限特性的接口可按需处理,比如默认禁止访问
        isAuthorized = false;
    }

    if (!isAuthorized)
    {
        context.Result = new ForbidResult();
    }
}

扩展说明

如果需要支持个别Action覆盖控制器定义的模块权限,可以先扫描当前Action方法上是否存在ModulePermissionAttribute,能取到值就优先用Action上的配置,取不到再回退读取控制器类上的特性,实现更灵活的权限标注规则。

内容的提问来源于stack exchange,提问作者BUlle7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 13:09:16