c# - "context.Resource as AuthorizationFilterContext"在 ASP.NET Core 3.0 中返回 null

标签 c# asp.net

我正在尝试按照教程实现自定义授权要求。这好像是context.Resource不再包含 AuthorizationFilterContext结果:

var authFilterContext = context.Resource as AuthorizationFilterContext;

返回 null其余的逻辑都失败了。我也无法获取查询字符串值,因为它为空。
以下是代码:
public class CanEditOnlyOtherAdminRolesAndClaimsHandler :
   AuthorizationHandler<ManageAdminRolesAndClaimsRequirement>
    {
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
       ManageAdminRolesAndClaimsRequirement requirement)
        {
            var authFilterContext = context.Resource as AuthorizationFilterContext;
            if (authFilterContext == null)
            {
                return Task.CompletedTask;
            }

            string loggedInAdminId =
                context.User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier).Value;

            string adminIdBeingEdited = authFilterContext.HttpContext.Request.Query["userId"];

            if (context.User.IsInRole("Admin") &&
                context.User.HasClaim(claim => claim.Type == "Edit Role" && claim.Value == "true") &&
                adminIdBeingEdited.ToLower() != loggedInAdminId.ToLower())
            {
                context.Succeed(requirement);
            }

            return Task.CompletedTask;
        }
    }
}

我应该如何在 ASP.NET Core 3.0 中解决这个问题?

最佳答案

这是由于 .NET Core 3.0 中的新端点路由。

引用下面的票。

This is because when using endpoint routing in ASP.NET Core 3.0:

Mvc will no longer add AuthorizeFilter to ActionDescriptor and ResourceInvoker will not call AuthorizeAsync() https://github.com/aspnet/AspNetCore/blob/90ab2cb965aeb8ada13bc4b936b3735ca8dd28df/src/Mvc/Mvc.Core/src/ApplicationModels/AuthorizationApplicationModelProvider.cs#L40

Mvc will add all Filter as metadata to endpoint.Metadata https://github.com/aspnet/AspNetCore/blob/5561338cfecac5ca4b1dda2f09a7f66153d0b5fe/src/Mvc/Mvc.Core/src/Routing/ActionEndpointFactory.cs#L348

instead by AuthorizationMiddleware call the AuthorizeAsync() and resouorce is Endpoint https://github.com/aspnet/AspNetCore/blob/5561338cfecac5ca4b1dda2f09a7f66153d0b5fe/src/Security/Authorization/Policy/src/AuthorizationMiddleware.cs#L63



新方法。
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CookieOrTokenAuthorizationRequirement requirement)
{
    if (context.Resource is Endpoint endpoint)
    {
        if (endpoint.Metadata.OfType<IFilterMetadata>().Any(filter => filter is MyFilter))
        {
            context.Succeed(requirement);
            return Task.CompletedTask;
        }
    }
}

https://github.com/dotnet/aspnetcore/issues/11075

还值得注意的是,使用新的上下文,您将无法像以前使用 AuthorizationFilterContext 那样访问路由数据。您需要将 IHttpContextAccessor 注入(inject)到 AuthorizationHandler 中。
// Ensure your handler is registered as scoped
services.AddScoped<IAuthorizationHandler, InvestorRequirementHandler>();


public class InvestorRequirementHandler : AuthorizationHandler<InvestorRequirement>
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public InvestorRequirementHandler(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, InvestorRequirement requirement)
    {
        var tenant = httpContextAccessor.HttpContext.GetRouteData().Values[ExceptionHandlerMiddleware.TenantCodeKey].ToString();
    }
}

关于c# - "context.Resource as AuthorizationFilterContext"在 ASP.NET Core 3.0 中返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59197631/

相关文章:

c# - 为 Visual Studio Enterprise 2015 创建自定义书面规则集

asp.net - Com 异常 : Word was unable to read this document. 它可能已损坏

c# - .Net Dictionary<int,int> 在大约 6,000,000 个条目处出现内存不足异常

C# 看不到带参数的 C++ 构造函数

c# - 为子类实现接口(interface)的多层次

c# - 如何格式化 serilog 属性名称?

javascript - ScriptManager 在 Mono 下不加载 javascript 方法

c# - Continue as First Statement in Concise If Else

c# - 在 ASP.Net 中提交表单时十进制值的文本框为空?

asp.net 使用 requireSSL 并且仍然能够检查用户是否在非 SSL 页面上进行了身份验证