首页 > 解决方案 > 在 netcore api 3.1 中读取 AuthorizationFilterContext

问题描述

我有一个工作的 netcore 2.2 项目,我在其中实施了一个检查 API 密钥的自定义策略。

在 startup.cs 我正在添加这样的策略

//Add Key Policy
services.AddAuthorization(options =>
{
    options.AddPolicy("AppKey", policy => policy.Requirements.Add(new AppKeyRequirement()));
});

在我的 AppKeyRequirement 中,我从 AuthorizationHandler 继承并解析传入请求中的密钥,如下所示

protected override Task HandleRequirementAsync(AuthorizationHandlerContext authContext, AppKeyRequirement requirement)
{
    var authorizationFilterContext = (AuthorizationFilterContext)authContext.Resource;
    var query = authorizationFilterContext.HttpContext.Request.Query;

    if (query.ContainsKey("key") && query.ContainsKey("app"))
    { // Do stuff

这在 netcore 3.1 中不起作用

我收到以下错误:

无法将类型为“Microsoft.AspNetCore.Routing.RouteEndpoint”的对象转换为类型“Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext”。

在核心 3 及更高版本中执行此操作的正确方法是什么?

正如 Kirk Larkin 所指出的,.net 3.0 及更高版本中的正确方法是将 IHttpContextAccessor 注入 Auth 处理程序并使用它。

我此时的问题是如何注入这个?我无法在 startup.cs 中传递它,或者至少我没有看到如何传递。

任何想法/提示将不胜感激。

标签: c#asp.net-core.net-core

解决方案


ASP.NET 核心 5.x

根据ASP.NET Core 5.0-preview7 及更高版本的公告Resource,该属性设置HttpContext为请求的当前值(使用终结点路由时)。这意味着以下示例将适用于 ASP.NET Core 5.0 及更高版本,而无需IHttpContextAccessor

public class AppKeyAuthorizationHandler : AuthorizationHandler<AppKeyRequirement>
{
    protected override Task HandleRequirementAsync(
        AuthorizationHandlerContext authContext, AppKeyRequirement requirement)
    {
        var httpContext = authContext.Resource as HttpContext;
        var query = httpContext.Request.Query;

        if (query.ContainsKey("key") && query.ContainsKey("app"))
        {
            // ...
        }
    }
}

RouteEndpoint仍然可用,使用httpContext.GetEndpoint().

ASP.NET 核心 3.x

在 ASP.NET Core 3.0 之前的版本中,IAuthorizationHandler在 MVC 管道期间调用 的实现。从 3.0 开始,它使用端点路由(默认情况下),这些实现由授权中间件 ( UseAuthorization()) 调用。这个中间件在 MVC 管道之前运行,而不是作为它的一部分。

此更改意味着AuthorizationFilterContext不再传递给授权处理程序。相反,它是 的一个实例RouteEndpoint,它不提供对HttpContext.

在您的示例中,您仅AuthorizationFilterContext用于获取HttpContext. 在 3.0+ 中,注入IHttpContextAccessor您的授权处理程序并使用它。这是一个完整性示例:

public class AppKeyAuthorizationHandler : AuthorizationHandler<AppKeyRequirement>
{
    private readonly IHttpContextAccessor httpContextAccessor;

    public AppKeyAuthorizationHandler(IHttpContextAccessor httpContextAccessor)
    {
        this.httpContextAccessor = httpContextAccessor;
    }

    protected override Task HandleRequirementAsync(
        AuthorizationHandlerContext authContext, AppKeyRequirement requirement)
    {
        var httpContext = httpContextAccessor.HttpContext;
        var query = httpContext.Request.Query;

        if (query.ContainsKey("key") && query.ContainsKey("app"))
        {
            // ...
        }
    }
}

您可能还需要IHttpContextAccessor注册ConfigureServices

services.AddHttpContextAccessor();

有关使用IHttpContextAccessor. _


推荐阅读