ASP.NET MVC应用程序的自定义401错误页面

时间:2018-07-12 11:15:51

标签: c# asp.net-mvc-5 windows-authentication custom-error-pages

我创建了一个使用集成Windows身份验证的ASP.NET MVC应用程序。实现了以下授权逻辑:

  1. 尝试通过NTLM从活动目录获取帐户凭据。

    • 如果收到凭据并且Windows帐户具有必需的权限,请执行请求的操作。
    • 否则,请转到第2条。
  2. 显示Windows身份验证对话框,因此用户可以提供另一个凭据: Authentication Dialog

    • 如果收到其他凭据,并且用户具有所需的权限,则执行请求的操作。
    • 如果未收到其他凭据或帐户权限少于要求的凭据,请重复第2条。
    • 如果取消了身份验证对话框,则显示401错误消息。

然后,我使用VictorySaber's solution为应用程序添加了自定义错误页面:

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>部分的技巧可以得出相同的结果。

我还发现proposal捕获了取消对话框时应该出现的 401.2 HTTP状态代码。但就我而言,代码永远不会发生。

如何使用用户友好的错误页面代替默认消息,但不更改身份验证对话框逻辑?

我需要实现以下要求:

  1. Windows身份验证对话框仅针对其AD帐户没有必需权限的用户出现,以允许该用户提供另一个凭据。
  2. 未提供正确的凭据或用户未取消它时,会出现该对话框。
  3. 仅当用户取消对话框时,才会显示自定义401错误页面。

1 个答案:

答案 0 :(得分:1)

一个小但重要的细节被遗漏了。默认情况下,只有设置了SetStatus标志,服务器才会保持响应不变。因此,有必要明确指定当HTTP状态代码为错误时IIS必须如何处理现有响应。

一种方法是在 Web.config 文件中配置<system.webServer>部分的<httpErrors>元素。只需将existingResponse属性值设置为PassThrough,以便在存在现有响应的情况下服务器保持响应不变。

<system.webServer>

  <!-- configuration settings -->

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

如果服务器提示您输入Windows用户帐户凭据,则配置可防止错误页面呈现。的 取消对话框后,响应将替换为错误页面。

通过通过HttpResponse的{​​{3}}属性禁用IIS自定义错误可以达到相同的结果。所以 另外,将以下行代码从该问题中删除即可解决问题:

Context.Response.TrySkipIisCustomErrors = true;

注意由于某种原因,第二种方法在我的生产服务器上不起作用。我认为,这需要其他服务器设置。