"context.Resource as AuthorizationFilterContext"在ASP.NET Core 3.0中返回null [英] "context.Resource as AuthorizationFilterContext" returning null in ASP.NET Core 3.0
问题描述
我正在尝试按照教程实施自定义授权要求.这好像是 context.Resource
不再包含 AuthorizationFilterContext
,因此:
I am trying to implement a custom authorization requirement following a tutorial. It seems like
context.Resource
no longer contains AuthorizationFilterContext
and as a result:
var authFilterContext = context.Resource as AuthorizationFilterContext;
返回 null
,其余逻辑失败.我也无法获取查询字符串值,因为它为null.以下是代码:
returns null
and the rest of the logic fails. I am also not able to get the query string value because it is null.
The following is the code:
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中解决此问题?
How should I fix this problem in ASP.NET Core 3.0?
推荐答案
这是由于.NET Core 3.0中新的端点路由所致.
This is due to the new endpoint routing in .NET Core 3.0.
引用以下票证.
这是因为在ASP.NET Core 3.0中使用终结点路由时:
This is because when using endpoint routing in ASP.NET Core 3.0:
Mvc将不再将AuthorizeFilter添加到ActionDescriptor中,并且ResourceInvoker将不会调用AuthorizeAsync() https://github.com/aspnet/AspNetCore/blob/90ab2cb965aeb8ada13bc4b936b3735ca8dd28df/src/Mvc/Mvc.Core/src/ApplicationModels/AuthorizationApplicationModelProvider.cs#L40
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会将所有过滤器作为元数据添加到端点. https://github.com/aspnet/AspNetCore/blob/5561338cfecac5ca4b1dda2f09a7f66153d0b5fe/src/Mvc/Mvc.Core/src/Routing/ActionEndpointFactory.cs#L348
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
代替AuthorizationMiddleware调用AuthorizeAsync()和资源是端点 https://github.com/aspnet/AspNetCore/blob/5561338cfecac5ca4b1dda2f09a7f66153d0b5fe/src/Security/Authorization/Policy/src/AuthorizationMiddleware.cs#L63
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注入到AuthorizationHandler中.
It's worth noting too that using the new context you won't be able to access route data as you were before with the AuthorizationFilterContext. You will need to inject an IHttpContextAccessor into the 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();
}
}
这篇关于"context.Resource as AuthorizationFilterContext"在ASP.NET Core 3.0中返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!