0

我有一个 MVC 3 站点,其中一些控制器/操作需要 Windows 身份验证,其他不需要,即是匿名的。

该站点运行良好一段时间,我可以访问匿名操作和经过身份验证的操作(无需提示,凭据在 Chrome/IE/FireFox 中自动传递),但随后身份验证停止工作,我开始收到提示输入从未使用过的凭据公认。

我必须重新启动整个服务器,或者将站点物理路径更改为另一个应用程序,发出经过身份验证的请求,该请求在返回原始站点时有效。然后情况是冲洗并重复,但我找不到它的模式。如果我什么都不做,身份验证就会中断。

我的 IIS 7.5 配置如下:

应用程序池

  • .NET 框架版本 - v4.0
  • 托管管道模式 - 集成
  • 应用程序池标识 - ApplicationPoolIdentity

地点

  • 匿名身份验证 - 已启用
  • 匿名用户身份 - IUSR [我相信这是默认设置]
  • ASP.NET 模拟 - 已禁用
  • 表单身份验证 - 已禁用
  • Windows 身份验证 - 已启用
  • Windows 身份验证扩展保护 - 关闭
  • Windows 身份验证启用内核模式身份验证 - 开
  • Windows 身份验证提供程序 - 协商、NTLM

控制器

// Anonymous Controller
    public class HomeController : Controller
    {
       public ActionResult Index()
       {
          return this.View();
       }
    }

// Authenticated Controller
    [Authorize]
    public class AnotherController : Controller
    {
       public ActionResult Index()
       {
          var viewModel = // create view model;
          return this.View(viewModel);
       }
    }

在任何时候,身份验证是否有效,对 /home/index 的 GET 都会返回 200。完全符合预期。当身份验证工作时,对 /another/index 的 GET 请求如下所示:

> GET /another/index
  Response: 401
  Response Headers: WWW-Authenticate: NTLM, WWW-Authenticate:Negotiate


> GET /another/index
  Request Header: Authorization: Negotiate TlRMIVNDUAACAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw==
  Response: 401
  Response Header: WWW-Authenticate: Negotiate TlRMTVNTUAACAAAACAAEADgAAAAVgoni2YSlwIHmCL4AAAAAAAAAAIgAiAA8AAAABgGxHQAAAA9GAFIAAgAEAEYAUgABABQARgBSAEkATgBUAFIAQQBOAEUAVAAEABQARgBSAC5ATgBEAFMALgBjAG8AbQADACoARgBSAKkATgBUAFIAQQBUAEUAVAAuAGCAcgAuAG4AZACzAC4AYvBvAG0ABQAOAE4ARABTAC6AYwBvAG0ABwAIAOST3lPK980BAAAAAA==

 > GET /another/index
   Request Headers: Authorization: Negotiate TlRMTVNTUAACAAAACAAEADgAAAAVgoni2YSlwIHmCL4AAAAAAAAAAIgAiAA8AAAABgGxHQAAAA9GAFIAAgAEAEYAUgABABQARgBSAEkATgBUAFIAQQBOAEUAVAAEABQARgBSAC5ATgBEAFMALgBjAG8AbQADACoARgBSAKkATgBUAFIAQQBUAEUAVAAuAGCAcgAuAG4AZACzAC4AYvBvAG0ABQAOAE4ARABTAC6AYwBvAG0ABwAIAOST3lPK980BAAAAAA==
   Response: 200

当身份验证中断对 /another/index 的 GET 请求时,如下所示:

> GET /another/index
  Response: 401
  Response Headers: WWW-Authenticate: NTLM, WWW-Authenticate:Negotiate


> GET /another/index
  Request Header: Authorization: Negotiate TlRMIVNDUAACAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw==
  Response: 401
  Response Headers: WWW-Authenticate: NTLM, WWW-Authenticate:Negotiate

此时,系统会提示我输入凭据,输入相同的请求,重新发送响应:

> GET /another/index
      Request Header: Authorization: Negotiate TlRMIVNDUAACAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw==
      Response: 401
      Response Headers: WWW-Authenticate: NTLM, WWW-Authenticate:Negotiate

有谁知道我是否有错误配置(我很确定我没有或者我根本不希望它工作),为什么身份验证会中断或如何阻止它?

非常感谢大家。

4

1 回答 1

0

所以事实证明这是由于 web.config 的 httpErrors 部分使用不当造成的

<httpErrors errorMode="Custom">
      <remove statusCode="401" subStatusCode="-1"/>
      <error statusCode="401" path="/Unauthorized" responseMode="ExecuteURL"/>
      <remove statusCode="403" subStatusCode="-1"/>
      <error statusCode="403" path="/Unauthorized" responseMode="ExecuteURL"/>
      <remove statusCode="404" subStatusCode="-1"/>
      <error statusCode="404" path="/NotFound" responseMode="ExecuteURL"/>
      <remove statusCode="500" subStatusCode="-1"/>
      <error statusCode="500" path="/ServerError" responseMode="ExecuteURL"/>
    </httpErrors>

这导致 NTLM 要求在需要身份验证时重新提交未从服务器发送的凭据。即应该发生什么请求,挑战(请重新提交凭据)响应。实际发生了什么请求,响应。挑战从未发送过。

正确的方法是完全删除此部分,并在我的错误控制器操作中使用扩展方法TrySkipIisCustomErrors

于 2013-03-25T16:23:49.247 回答