为ASP.NET MVC应用程序定制401错误页面

9
我创建了一个使用集成 Windows 认证的 ASP.NET MVC 应用程序,并实现了以下授权逻辑:
  1. 尝试通过 NTLM 从 Active Directory 获取帐户凭据。

    • 如果收到凭据,并且 Windows 帐户具有所需权限,则执行请求的操作。
    • 否则,进入第2条款。
  2. 显示 Windows 认证对话框,以便用户提供其他凭据: Authentication Dialog

    • 如果接收到其他凭据,并且用户具有所需权限,则执行请求的操作。
    • 如果未收到其他凭据或帐户权限不足,则重复第2条款。
    • 如果取消认证对话框,则显示401错误消息。
然后,我使用 VictorySaber 的解决方案 为应用程序添加了自定义错误页:
protected void Application_EndRequest()
{
    int status = Response.StatusCode;
    string actionName;
    if (status >= 400 && status < 500)
    {
        switch (status)
        {
            case 401:
                actionName = "Unauthorized";
                break;

            // Handle another client errors

            default:
                actionName = "BadRequest";
                break;
            }
        }
    else if (status >= 500 && status < 600)
    {
        switch (status)
        {
            case 501:
                actionName  = "NotImplemented";
                break;

            // Handle another server errors

            default:
                actionName  = "InternalServerError";
                break;
        }
    }
    if (!String.IsNullOrEmpty(actionName))
    {
        Response.Clear();
        var rd = new RouteData();
        rd.Values["controller"] = "Errors";
        rd.Values["action"] = actionName;
        IController c = new ErrorsController();
        c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));
    }
}

作为结果,我的友好错误页面已经呈现出来了。但是Windows身份验证对话框没有出现。如果出现401 HTTP状态码,则会立即显示401错误消息。在web.config文件的<httpErrors>部分的技巧可以得到相同的结果。
此外,我发现建议捕获应该在取消对话框时发生的401.2 HTTP状态代码。但在我的情况下,代码从未出现。
如何使用用户友好的错误页面而不改变身份验证对话框逻辑?
我需要实现以下要求:
1. 仅向AD帐户没有所需权限的用户显示Windows身份验证对话框,以允许用户提供其他凭据。 2. 仅当提供了正确的凭据或用户没有取消它时,才会出现对话框。 3. 仅在用户取消对话框时显示自定义401错误页面。

这个有用吗?https://stackoverflow.com/questions/10993685/provide-a-custom-error-page-for-401-failed-authorization - Alen Genzić
1
@AlenGenzić,我的ErrorsController的操作被调用,但在身份验证对话框之前会调用未经授权的操作。我期望只有当用户取消身份验证对话框时才会调用未经授权的操作。 - Alexander
1个回答

1
默认情况下,只有在设置了SetStatus标志时,服务器才不会改变响应。因此,当HTTP状态码为错误时,必须明确指定IIS对现有响应要执行的操作。
一种方法是配置Web.config文件中<system.webServer>部分的<httpErrors>元素。只需将existingResponse属性值设置为PassThrough,这样,如果存在现有响应,则服务器将保持响应不变。
<system.webServer>

  <!-- configuration settings -->

  <httpErrors errorMode="Custom" existingResponse="PassThrough" />
</system.webServer>

配置可以防止在服务器提示输入Windows用户账户凭据时呈现错误页面。如果取消对话框,响应将被替换为错误页面。
通过禁用HttpResponseTrySkipIisCustomErrors属性,可以实现相同的结果。因此,将以下行添加到问题中的代码即可解决问题:
Context.Response.TrySkipIisCustomErrors = true;

注意第二种方法在我的生产服务器上由于某些原因无法使用。我认为需要进行额外的服务器设置。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接