在Netcore API 3.1中读取AuthorizationFilterContext


9

我有一个正在运行的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中传递它,或者至少我不知道如何。

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

Answers:


14

在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"))
        {
            // ...
        }
    }
}

您可能还需要注册IHttpContextAccessorConfigureServices

services.AddHttpContextAccessor();

看到 使用的更多信息,从自定义组件使用HttpContextIHttpContextAccessor


1
感谢您的提示。我正在尝试创建一个策略,如果缺少API密钥,该调用将被拒绝。我们可以不再使用//添加密钥策略服务吗?如果不是,我该如何在调用控制器操作之前拦截该调用?
w2olves

1
是的,它仍然和以前一样。
柯克·拉金

构造函数期望IHttpContextAccessor在Startup.cs中创建策略时如何传递它?services.AddAuthorization(options => {options.AddPolicy(“ AppKey”,policy => policy.Requirements.Add(new AppKeyRequirement()))}); 我还可以为AppKeyAuthorizationHandler创建一个新的默认构造函数,然后创建httpContextAccessor.HttpContext;。请求传入时为null。有什么想法吗?
w2olves

1
您可以使用DI添加处理程序,该处理程序将为您创建一个实例并将其传递给IHttpContextAccessor。请参阅文档
柯克·拉金
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.