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

ASP.NET Core 5中IOperationFilter如何判断Action是否允许匿名访问

问题原因

你现有代码的问题在于:只有当授权过滤器/匿名过滤器被注册到过滤器管道(比如全局注册、或者通过[TypeFilter]等方式注册)时,才会出现在FilterDescriptors集合中。如果只是直接在Controller/Action上加[Authorize]、[AllowAnonymous]特性,没有额外做过滤器注册的话,FilterDescriptors里是找不到对应过滤器实例的,所以两个变量都会返回false。

正确实现方案

直接从ControllerActionDescriptor的方法和所属类的特性中做判断,特性的优先级符合ASP.NET Core的默认规则:Action级特性优先级高于Controller级特性。

实现代码

public class AddTenantHeaderParameterOperationFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        // 先转成ControllerActionDescriptor获取Controller和Action的元数据
        if (context.ApiDescription.ActionDescriptor is not ControllerActionDescriptor controllerActionDescriptor)
        {
            // 非Controller接口(比如Minimal API)可以按需处理,这里直接跳过
            return;
        }

        // 优先判断是否有AllowAnonymous特性:Action级优先,其次Controller级
        var hasAllowAnonymous = controllerActionDescriptor.MethodInfo.GetCustomAttributes(true)
            .Any(attr => attr is IAllowAnonymous) 
            || controllerActionDescriptor.ControllerTypeInfo.GetCustomAttributes(true)
            .Any(attr => attr is IAllowAnonymous);
        
        if (hasAllowAnonymous)
        {
            return;
        }

        // 判断是否需要授权:Action有[Authorize] 或 Controller有[Authorize]
        var hasAuthorize = controllerActionDescriptor.MethodInfo.GetCustomAttributes(true)
            .Any(attr => attr is IAuthorizeData)
            || controllerActionDescriptor.ControllerTypeInfo.GetCustomAttributes(true)
            .Any(attr => attr is IAuthorizeData);

        // 如果你启用了全局授权策略(比如Program里加了app.MapControllers().RequireAuthorization())
        // 那不需要判断hasAuthorize,只要没有AllowAnonymous就需要授权,直接注释掉下面的判断即可
        if (!hasAuthorize)
        {
            return;
        }

        // 你的添加头部参数逻辑
        operation.Parameters ??= new List<OpenApiParameter>();
        operation.Parameters.Add(new OpenApiParameter
        {
            Name = "X-TenantId",
            In = ParameterLocation.Header,
            Required = true,
            Schema = new OpenApiSchema
            {
                Type = "string"
            }
        });
    }
}
补充说明

如果你的项目用了Minimal API,需要额外处理EndpointMetadata里的特性,逻辑和上面一致,从context.ApiDescription.ActionDescriptor.EndpointMetadata里判断是否有IAllowAnonymous和IAuthorizeData即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 16:06:00