问题
简而言之,如何防止未经授权的ChildActions返回401代码并返回空结果 .
上下文
我的应用程序使用 NTLM 在网络上进行身份验证 . 我也想处理匿名识别,对于没有能力的设备,或者如果有人通过某些代理 .
一个是Web应用程序,有一些绝对需要登录才能查看的控制器/操作以及一些可以匿名查看的控制器/操作 . 对于那些我最初使用以下内容的身份验证是强制性的:
[Authorize()]
public class SomeController : BaseController
哪个按预期工作并返回 401 Status Code (Unauthorized) .
问题从允许匿名的页面开始 . 因为这些页面的部件使用RenderAction来渲染碎片 that requires authentication .
在前端的本地开发服务器上一切看起来都很好,但是对于任何需要身份验证的任何小页面都会返回401页面 . 所以我创建了一个自定义Authorize属性:
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
public bool Ignore401ChildAction { get; set; }
public CustomAuthorizeAttribute()
: base() {
this.Ignore401ChildAction = true;
}
protected override void HandleUnauthorizedRequest( AuthorizationContext filterContext ) {
base.HandleUnauthorizedRequest( filterContext );
if( this.Ignore401ChildAction && filterContext.IsChildAction ) {
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
}
}
然后在前端它似乎产生有和没有IIS的正确行为 . 但是在后端,即使页面呈现完整,它也会返回401
所以我将以下内容添加到我的CustomAttribute而不是 TrySkipIisCustomErrors
filterContext.HttpContext.Response.StatusCode = 200;
filterContext.Result = new EmptyResult();
在匿名中一切都很好,但是当启用NTLM时,当控制器没有CustomAuthorize属性时,服务器不会请求身份验证 . 它似乎只是在强制要求时才提出要求,而不是当它们可用时 .
谢谢,
编辑
经过大量的搜索,挖掘和摆弄,意识到真正的问题是匿名识别将优先于Windows / NTLM . 如果启用了 Anonymous 和 Windows 身份验证,则只有在匿名身份验证失败时才会执行 Windows .
解决方案
(不完美和有点hackish但它有效)
将以下函数添加到BaseController,然后从非强制要求身份验证的视图调用,或者只是从 _Layout 视图中调用它 .
注意:即使页面将以匿名方式正确呈现, 401 status code will still be returned.
[CustomAuthorize]
public ActionResult Auth() {
return new EmptyResult();
}