【问题标题】:Reading the AuthorizationFilterContext in netcore api 3.1在 netcore api 3.1 中读取 AuthorizationFilterContext
【发布时间】:2019-10-25 20:50:51
【问题描述】:

我有一个有效的 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


    【解决方案1】:

    ASP.NET Core 5.x

    基于 ASP.NET Core 5.0-preview7 及更高版本的 announcementResource 属性设置为请求的当前 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 Core 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"))
            {
                // ...
            }
        }
    }
    

    您可能还需要在ConfigureServices 中注册IHttpContextAccessor

    services.AddHttpContextAccessor();
    

    有关使用IHttpContextAccessor 的更多信息,请参阅Use HttpContext from custom components

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-11
      • 2021-02-06
      • 2021-11-21
      • 2021-05-07
      相关资源
      最近更新 更多