我创建了一个使用集成Windows身份验证的ASP.NET MVC应用程序。实现了以下授权逻辑:
尝试通过NTLM从活动目录获取帐户凭据。
显示Windows身份验证对话框,因此用户可以提供另一个凭据:
然后,我使用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状态代码。但就我而言,代码永远不会发生。
如何使用用户友好的错误页面代替默认消息,但不更改身份验证对话框逻辑?
我需要实现以下要求:
答案 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;
注意。 由于某种原因,第二种方法在我的生产服务器上不起作用。我认为,这需要其他服务器设置。