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

Ale*_*der 8 c# windows-authentication custom-error-pages asp.net-mvc-5

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

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

    • 如果收到凭据且Windows帐户具有所需权限,则执行请求的操作.
    • 否则请转至第2条.
  2. 显示Windows身份验证对话框,以便用户可以提供其他凭据: 身份验证对话框

    • 如果收到其他凭据且用户具有所需权限,则执行请求的操作.
    • 如果未收到其他凭据或帐户权限少于其要求,则重复第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));
    }
}
Run Code Online (Sandbox Code Playgroud)

结果我呈现了友好的错误页面.但是不会出现Windows身份验证对话框.如果出现401 HTTP状态代码,则会立即显示401错误消息.web.config文件<httpErrors>部分的技巧给出了相同的结果.

此外,我发现建议捕获取消对话框时应该发生的401.2 HTTP状态代码.但就我而言,代码永远不会发生.

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

我需要实现以下要求:

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

Ale*_*der 1

SetStatus默认情况下,仅当设置了该标志时,服务器才会保持响应不变。因此,有必要明确指定当 HTTP 状态代码为错误时 IIS 必须如何处理现有响应。

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

<system.webServer>

  <!-- configuration settings -->

  <httpErrors errorMode="Custom" existingResponse="PassThrough" />
</system.webServer>
Run Code Online (Sandbox Code Playgroud)

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

TrySkipIisCustomErrors通过的属性禁用 IIS 自定义错误可以实现相同的结果HttpResponse。因此,在问题的代码中添加以下行可以解决问题:

Context.Response.TrySkipIisCustomErrors = true;
Run Code Online (Sandbox Code Playgroud)

笔记由于某种原因,第二种方法在我的生产服务器上不起作用。我认为,它需要额外的服务器设置。