asp.net-mvc MVC 4 AuthorizeAttribute.HandleUnauthorizedRequest ViewResult - 无限循环
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20012795/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MVC 4 AuthorizeAttribute.HandleUnauthorizedRequest ViewResult - infinite loop
提问by Sonic Soul
i've stepped through my code a million times and can't find a problem with my implementation..
我已经遍历了我的代码一百万次,但在我的实现中找不到问题。
in custom AuthorizeAttribute i overwrote 2 methods
在自定义 AuthorizeAttribute 中,我覆盖了 2 个方法
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (!httpContext.Request.IsAuthenticated)
return false;
var routeData = httpContext.Request.RequestContext.RouteData;
var ctrl = routeData.Values["controller"].ToString();
var action = routeData.Values["action"].ToString();
var user = httpContext.User.Identity.Name;
_logger.Info("[logging all the details]");
return ctrl == "SomeController";
}
protected override void HandleUnauthorizedRequest(AuthorizationContext ctx)
{
ctx.Result = new ViewResult { ViewName = "Unauthorized" };
// base.HandleUnauthorizedRequest(ctx);
}
the authorization logic is mocked to return false only on specific controller, and i've stepped through this to verify it's working correctly.
授权逻辑被模拟为仅在特定控制器上返回 false,我已经逐步验证它是否正常工作。
above code will cause infinite loop. in my log i can see that line hit 666 times (coincidence?) ..
上面的代码会导致无限循环。在我的日志中,我可以看到那条线命中了 666 次(巧合?)..
if i do call base.HandleUnauthorizedRequest(ctx), all i get is a blank page. so i reflected what the base does, and it's this
如果我打电话给 base.HandleUnauthorizedRequest(ctx),我得到的只是一个空白页。所以我反映了基地的作用,就是这个
filterContext.Result = new HttpUnauthorizedResult();
so this explains why it renders a blank page instead of redirecting to Unauthorized.cshtml. what i'm not sure about, is why does it go into an infinite loop if i don't call the base.
所以这解释了为什么它呈现一个空白页面而不是重定向到 Unauthorized.cshtml。我不确定的是,如果我不调用 base,它为什么会进入无限循环。
p.s.
ps
i've verified that if i put the wrong Unauthorized view it will error out (but still hangs indefinitely)
我已经验证,如果我输入错误的未经授权的视图,它会出错(但仍会无限期挂起)
System.InvalidOperationException: The view 'Unauthorized11' or its master was not found or no view engine supports the searched locations
回答by Sonic Soul
Here is the implementation that i ended up going with and it's working very well.
这是我最终采用的实现,并且运行良好。
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
// this is overriden for kendo menus to hide
var ctrl = filterContext.RequestContext.RouteData.GetRequiredString("controller");
var action = filterContext.ActionDescriptor.ActionName;
[custom authorization logic on action/ctrl]
// useful to determine if it's authorizing current controller path or menu links
var path = filterContext.HttpContext.Request.PhysicalPath;
_authorizingCurrentPath = path.Contains(ctrl) || path.EndsWith("WebUI") ;
if (userAuth < requiredAuth)
HandleUnauthorizedRequest(filterContext);
}
protected override void HandleUnauthorizedRequest(AuthorizationContext ctx)
{
if (!ctx.HttpContext.User.Identity.IsAuthenticated)
base.HandleUnauthorizedRequest(ctx);
else {
if (_authorizingCurrentPath) {
// handle controller access
ctx.Result = new ViewResult { ViewName = "Unauthorized" };
ctx.HttpContext.Response.StatusCode = 403;
}
else {
// handle menu links
ctx.Result = new HttpUnauthorizedResult();
ctx.HttpContext.Response.StatusCode = 403;
}
}
}
回答by James
The default implementation of AuthorizeAttributesets the response on the action context, by not calling into the base the response is never set which causes the filter to repeat the authorization process until a response is set (hence the infinite loop).
AuthorizeAttribute的默认实现在操作上下文中设置响应,通过不调用基类,响应永远不会设置,这会导致过滤器重复授权过程,直到设置响应(因此是无限循环)。
You can see this logic in the AuthorizationFilterAttributeclass which AuthorizeAttribute derives from.
您可以在AuthorizeAttribute 派生自的AuthorizationFilterAttribute类中看到此逻辑。

