我正在尝试按照教程实现自定义授权要求。这好像是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/