2 回答

TA貢獻(xiàn)1796條經(jīng)驗(yàn) 獲得超10個(gè)贊
我已經(jīng)對(duì)框架源進(jìn)行了一些挖掘,并找到了一種以授權(quán)處理程序方式進(jìn)行這項(xiàng)工作的方法。
授權(quán)過程的入口點(diǎn)是AuthorizeFilter。過濾器上下文有一個(gè)接受IActionResult的Result屬性。通過設(shè)置此屬性,您可以縮短請(qǐng)求并顯示您想要的任何操作結(jié)果(包括視圖)。這是解決問題的關(guān)鍵。
如果遵循執(zhí)行路徑,您會(huì)發(fā)現(xiàn)過濾器上下文已傳遞給授權(quán)組件,并且在IAuthorizationHandler.HandleRequirementAsync方法中可用。您可以通過向下轉(zhuǎn)換從上下文對(duì)象的Resource屬性中獲取它(如 OP 所示)。
還有一件更重要的事情:您必須從授權(quán)處理程序返回成功,否則最終不可避免地會(huì)發(fā)生重定向。(如果您查看IPolicyEvaluator的默認(rèn)實(shí)現(xiàn),這將變得清晰。)
所以把這一切放在一起:
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貢獻(xiàn)1827條經(jīng)驗(yàn) 獲得超8個(gè)贊
我認(rèn)為 AuthorizationHandler 絕對(duì)是放置這個(gè)邏輯的更好的地方。但是 - 如果我理解正確 - 您的問題是要調(diào)用的操作在此處理程序執(zhí)行時(shí)已被選擇,因此您無法再更改路由。
當(dāng)然,標(biāo)準(zhǔn)方法是啟動(dòng)重定向,但您希望避免這種情況以保留當(dāng)前 URL。
鑒于上述情況,我可以想到一種方法:全局操作過濾器。
操作過濾器可以在調(diào)用單個(gè)操作方法之前和之后立即運(yùn)行代碼。它們可用于操作傳遞給動(dòng)作的參數(shù)和動(dòng)作返回的結(jié)果。
該OnActionExecuting方法似乎是把你的邏輯,因?yàn)樵谶@一點(diǎn)上,你可以訪問操作方法的屬性在正確的地方,你有機(jī)會(huì)短路的處理(通過設(shè)置結(jié)果的財(cái)產(chǎn)ActionExecutingContext參數(shù))如果用戶被阻止。
如果您不熟悉過濾器的概念,您將在這篇 MSDN 文章 中找到所有詳細(xì)信息。
- 2 回答
- 0 關(guān)注
- 207 瀏覽
添加回答
舉報(bào)