2 回答
TA贡献1796条经验 获得超10个赞
我已经对框架源进行了一些挖掘,并找到了一种以授权处理程序方式进行这项工作的方法。
授权过程的入口点是AuthorizeFilter。过滤器上下文有一个接受IActionResult的Result属性。通过设置此属性,您可以缩短请求并显示您想要的任何操作结果(包括视图)。这是解决问题的关键。
如果遵循执行路径,您会发现过滤器上下文已传递给授权组件,并且在IAuthorizationHandler.HandleRequirementAsync方法中可用。您可以通过向下转换从上下文对象的Resource属性中获取它(如 OP 所示)。
还有一件更重要的事情:您必须从授权处理程序返回成功,否则最终不可避免地会发生重定向。(如果您查看IPolicyEvaluator的默认实现,这将变得清晰。)
所以把这一切放在一起:
public class BlockedHandler : AuthorizationHandler<BlockedRequirement>
{
private Task HandleBlockedAsync(AuthorizationFilterContext filterContext)
{
// create a model for the view if needed...
var model = new BlockedModel();
// do some processing if needed...
var modelMetadataProvider = filterContext.HttpContext.RequestServices.GetService<IModelMetadataProvider>();
// short-circuit request by setting the action result
filterContext.Result = new ViewResult
{
StatusCode = 403, // Client cannot access the requested resource
ViewName = "~/Views/Shared/Blocked.cshtml",
ViewData = new ViewDataDictionary(modelMetadataProvider, filterContext.ModelState) { Model = model }
};
return Task.CompletedTask;
}
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, BlockedRequirement requirement)
{
if (context.User.HasClaim(c => c.Type == UserClaimTypes.BlockedFrom) &&
context.Resource is AuthorizationFilterContext filterContext &&
filterContext.ActionDescriptor is ControllerActionDescriptor descriptor)
{
var allowBlocked = descriptor.ControllerTypeInfo.CustomAttributes
.Concat(descriptor.MethodInfo.CustomAttributes)
.Any(x => x.AttributeType == typeof(AllowBlockedAttribute));
if (!allowBlocked)
await HandleBlockedAsync(filterContext);
}
// We must return success in every case to avoid forbid/challenge.
context.Succeed(requirement);
}
}
TA贡献1827条经验 获得超8个赞
我认为 AuthorizationHandler 绝对是放置这个逻辑的更好的地方。但是 - 如果我理解正确 - 您的问题是要调用的操作在此处理程序执行时已被选择,因此您无法再更改路由。
当然,标准方法是启动重定向,但您希望避免这种情况以保留当前 URL。
鉴于上述情况,我可以想到一种方法:全局操作过滤器。
操作过滤器可以在调用单个操作方法之前和之后立即运行代码。它们可用于操作传递给动作的参数和动作返回的结果。
该OnActionExecuting方法似乎是把你的逻辑,因为在这一点上,你可以访问操作方法的属性在正确的地方,你有机会短路的处理(通过设置结果的财产ActionExecutingContext参数)如果用户被阻止。
如果您不熟悉过滤器的概念,您将在这篇 MSDN 文章 中找到所有详细信息。
- 2 回答
- 0 关注
- 173 浏览
添加回答
举报