1

问题

长话短说,您如何防止未经授权的 ChildActions 返回 401 代码并返回空结果。

语境

我的应用程序使用NTLM在网络上进行身份验证。我还想处理匿名身份识别,对于不支持NTLM的设备,或者如果有人通过某些代理。

Web 应用程序之一是绝对需要登录才能查看的控制器/操作,还有一些可以匿名查看的控制器/操作。对于那些在我最初使用以下内容时必须进行身份验证的人:

[Authorize()]
public class SomeController : BaseController

它按预期工作并返回401 状态代码 (Unauthorized)

问题从允许匿名的页面开始。因为这些页面的部分使用 RenderAction 来呈现需要身份验证的部分。

在前端的本地开发服务器上,一切看起来都很好,但是对于IIS,任何具有任何需要身份验证的小块的页面都会返回 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。如果启用了匿名Windows身份验证,则Windows将仅在匿名身份验证失败时执行。

解决方案

(不完美,有点骇人听闻,但它有效)

将以下函数添加到您的 BaseController 然后从不需要身份验证的视图中调用,或者只是从您的_Layout视图中调用它。

注意:即使页面将正确呈现为匿名,仍将返回 401 状态代码。

[CustomAuthorize]
public ActionResult Auth() {
    return new EmptyResult();
}
4

0 回答 0