在 ASP.NET Core 6 中,有没有一种方法可以根据使用 URL 来限制某些操作方法?

In ASP.NET Core 6, is there a way to restrict certain action methods based on which URL is used?

在默认的 ASP.NET Core web API 应用程序中以 .NET 6 为目标,默认情况下它公开两个 URL 端点:一个位于 http://localhost:50xx,另一个在 https://localhost:70xx.

我想要做的是将第一个 (http) 用于 internal/trusted 客户端请求,将第二个 (https) 用于 internet/public 请求。所以很自然地,我想根据请求的来源来区别对待请求。

对于这两种类型的请求,我想使用 simple/default 路由匹配,但是 ,对于 HTTPS 请求,我想在选定的操作方法上启用白名单。结果是大多数请求根本无法通过 HTTPS 获得。

我觉得一定有一些简单的方法可以做到这一点,因为框架(和默认的应用程序模板)似乎已经通过提供 URLs...必须有一些方便的方法可以完成我所描述的,但我没有在文档中遇到它们。

谢谢

实施并应用全局自定义 ActionFilterAttribute,禁止 HTTPS 请求,但应用了自定义属性的 Controllers/Actions 除外。

1. 创建将应用于支持 HTTPS 请求的 contoller/methods 的自定义属性:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AllowHttpsAttribute : Attribute { }

2. 创建自定义 ActionFilterAttribute 当控制器或操作没有 [ 时 short-circuits 通过 HTTPS 发出请求=16=] applied(short-circitung 是通过给 context.Result 赋值实现的):

public class HttpOnlyActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var isHttps = context.HttpContext.Request.Scheme == Uri.UriSchemeHttps;
        if (isHttps && HttpsNotSupported(context))
        {
            context.Result = new BadRequestResult();
        }
    }

    private bool HttpsNotSupported(ActionContext context)
    {
        return context.ActionDescriptor is ControllerActionDescriptor x &&
        !x.ControllerTypeInfo.GetCustomAttributes<AllowHttpsAttribute>().Any() &&
        !x.MethodInfo.GetCustomAttributes<AllowHttpsAttribute>().Any();
    }
}

3. 全局应用 HttpOnlyActionFilter(在 Program.cs):

builder.Services.AddControllers(x => x.Filters.Add<HttpOnlyActionFilter>());

用法:

应用于操作:

public class Controller : ControllerBase
{
    // Allow requests over HTTPS 
    [HttpGet, AllowHttps]
    public ActionResult Action1() => ...;

    // Disallow requests over HTTPS 
    [HttpGet]
    public ActionResult Action2() => ...;
}

应用于控制器:

[AllowHttps] // Allow requests over HTTPS 
public class Controller : ControllerBase
{
  ...
}