在 AuthorizationHandler<T> 中获取 HTTP 请求方法的正确方法是什么?

What is the proper way of getting the HTTP request method in an AuthorizationHandler<T>?

我正在尝试做的事情的简化版本:我想编写一个授权策略,如果在数据库中设置了标志,它将阻止不是 GET 的请求。我注册了我的政策,处理程序代码在我的控制器上运行良好,但我不确定获取 HTTP 方法类型的最佳方式是什么。

控制器看起来像这样:

[Authorize(Policy = "Test")]
public class MyController : ControllerBase
{
    // ...
}

我的处理程序如下所示:

protected override async Task HandleRequirementAsync(AuthorizationHandlerContext ctx, MyRequirement req)
{
    // Fetch some flag from db

    if (!flag)
    {
        ctx.Succeed(req);
        return;
    }

    var method = GetRequestMethodFromCtx(ctx.Resource);

    if (method == HttpMethods.Get)
    {
        ctx.Succeed(req);
    }
    else
    {
        ctx.Fail();
    }
}

我注意到,对于单个请求,我的处理程序会被多次调用,而且 ctx.Resource 并不总是相同的类型。第一次是 RouteEndpoint,之后是 AuthorizationFilterContextSealed.

我是否应该只从 RouteEndpoint 中提取 HTTP 方法并忽略第二个调用?另外,为什么要多次调用处理程序?

为了访问 HttpContext 对象,您可以使用 IHttpContextAccessor 服务。

您可以简单地将其作为授权处理程序的依赖项 class 并且 ASP.NET 核心依赖项注入将为您提供服务。

为了使用依赖注入注册它,您需要在 Startup class.

ConfigureServices 方法中调用 services.AddHttpContextAccessor()

您可以从 HttpContext 访问 Request,然后访问 Method 属性(参见 here)。

详见official documentation

我不太清楚您的要求,但为了防止使用特定 HTTP 动词调用操作方法,有一种更简单的方法。你只需要使用内置的路由属性,你可以找到更多信息here.