IIS 7.5 中的 Windows 身份验证失败

Posted

技术标签:

【中文标题】IIS 7.5 中的 Windows 身份验证失败【英文标题】:Windows authentication failing in IIS 7.5 【发布时间】:2012-09-23 12:50:34 【问题描述】:

我正在为我的公司构建一个简单的内部应用程序,它需要 Windows 身份验证以确保安全。所有其他身份验证模式均被禁用。我陷入了 Internet Explorer 提示输入凭据 3 次,然后失败并出现以下错误的情况:

未授权

HTTP 错误 401。请求的资源需要用户身份验证。

然后我创建了一个简单的网站来测试这一点。我在 IIS 中创建了一个新站点,将其放在自己的端口(:8111,随机选择)上,在其中放置一个静态“default.htm”文件,禁用匿名身份验证,然后启用 Windows 身份验证。其他一切都保持默认设置。分配端口号是因为我们在这台机器上有多个站点都共享同一个 IP。

这里有几个场景:

从 Web 服务器本身浏览到 http://localhost:8111/ 有效 很好

从另一台计算机浏览到 http://ServerIPaddress:8111/ 工作正常

从另一台计算机浏览到 http://ServerName:8111/ 失败 (要求凭据 3 次,然后给出 401 错误)

到目前为止,我一直在网上搜索并试图找到一个没有运气的解决方案。要么我没有找到它,要么我对我正在阅读的内容不够了解。任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

在与此问题斗争 2 天后,刚刚在同事的帮助下找到了解决方案。这是他写的:

Windows 身份验证有 2 个提供程序(协商和 NTLM)。 将网站身份验证设置为 Windows 身份验证时, 在突出显示 Windows 身份验证时,单击提供程序 右窗格或 IIS 管理器上的链接,然后将 NTLM 移到顶部。经过 默认协商在最上面,这就是为什么你得到一个 身份验证提示。

【讨论】:

+1 这对我来说是成功的,而更深入和正确的答案是调查 Negotiate 失败的原因,这确实很快就突出了问题所在。 为此损失了半天。感谢您的修复。 这也为我解决了。就我而言,我收到 504 Gateway Timeout 错误。 @seph - 我在下面发布了一个新答案,其中引用了一篇 msdn 文章,该文章显示了此问题的修复,以便使用 Negotiate。 我删除了 Negotiate 并修复了它但是为什么呢??一个解释会很好。【参考方案2】:

浏览使用集成身份验证的网站时出现错误 401.1。

解决方案

禁用环回检查

* In Registry Editor, locate and then click the following registry key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa

* Right-click Lsa, point to New, and then click DWORD Value.
* Type DisableLoopbackCheck, and then press ENTER.
* Right-click DisableLoopbackCheck, and then click Modify.
* In the Value data box, type 1, and then click OK.

http://support.microsoft.com/kb/896861

【讨论】:

谢谢!!!这对我有用,我从过去几个小时的开发者痛苦和沮丧中解脱出来。 谢谢你。我只是瞥了一眼,看到了这个注册表编辑。当上述 NTLM 修复不起作用时,我建议这是确定的下一步。刚刚验证了我花了很多时间来解决这个问题! 这只会在从托管网站的同一台机器上浏览时影响 Windows 身份验证 这很危险。不要全局禁用环回检查...它的存在是有原因的。 我曾经是一名共享点开发人员,并且必须在每个开发服务器构建上都这样做......但我已经在 MVC 领域有一段时间了,完全忘记了,所以谢谢你。 【参考方案3】:

如果在将 NTML 移至提供商列表顶部后仍然无法正常工作,请尝试完全删除 Negotiate,以便只剩下 NTML。

这为我解决了问题 - 将 NTML 移到顶部对 Windows Server 2012 和 IIS 8.5 没有帮助。我在以下 *** 问题中找到了解决方案:IIS 7.5 Windows Authentication Not Working in Chrome

【讨论】:

【参考方案4】:

我个人建议不要在您的服务器上全局禁用环回检查(即:NOT 在您的注册表中将DisableLoopbackCheck 设置为1 的值)。这是一个安全漏洞。请仅对已知主机禁用。

这是一个 Powershell 函数,可帮助您指明正确的方向。

function Add-LoopbackFix

    param(
        [parameter(Mandatory=$true,position=0)] [string] $siteHostName
    )

    $ErrorActionPreference = "Stop"

    Write-Host "Adding loopback fix for $siteHostName" -NoNewLine

    $str = Get-ItemProperty -Name "BackConnectionHostNames" -path 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0' -erroraction silentlycontinue

    if ($str)  
        if($($str.BackConnectionHostNames) -like "*$siteHostName*")
        
            Write-Host "`tAlready in place" -f Cyan
         else
            $str.BackConnectionHostNames += "`n$siteHostName"
            Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" -Name "BackConnectionHostNames" -Value $str.BackConnectionHostNames 
            Write-Host "`tDone" -f Green
        
     else 
        New-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" -Name "BackConnectionHostNames" -Value $siteHostName -PropertyType "MultiString" 
        Write-Host "`tDone" -f Green
    

    Write-Host "`tnote: we are not disabling the loopback check all together, we are simply adding $siteHostName to an allowed list." -f DarkGray

> Add-LoopbackFix "ServerName"

Source

【讨论】:

在内部开发服务器上禁用它应该没有风险。如果它是生产服务器,您可能会远程访问它,并且无论如何都可以不理会环回。 @Ryios,即使在 Dev 中,推荐的方法是按域而不是全局进行。在生产环境中,我们有很多应用程序 (SOA) 调用同一服务器上的其他应用程序。【参考方案5】:

问这个问题已经有一段时间了,但我知道很多人经常遇到这个问题。此处描述了一个更合适的解决方法:Kernel-mode authentication。我们在几个月前就实施了这个,效果很好。

这里还有一个很好的解释:MORE 2008 AND KERBEROS: AUTHENTICATION DENIED, APP POOL ACCOUNT BEING INGNORED

要应用于单个站点:

cd %windir%\system32\inetsrv
set SiteName=TheSiteName
appcmd.exe set config "%SiteName%" -section:system.webServer/security/authentication/windowsAuthentication /useKernelMode:"True" /useAppPoolCredentials:"True" /commit:apphost

或适用于所有网站:

%windir%\system32\inetsrv\appcmd.exe set config -section:windowsAuthentication /useAppPoolCredentials:"True" /commit:apphost

【讨论】:

嗯,我希望能解释为什么删除 Negotiate 会神奇地修复它,但它不在这里。我尝试取消勾选内核模式并重新设置协商,但它没有修复它。删除 Negotiate 确实解决了它...但是为什么呢? 这绝对是我需要的修复。另一方面,我注意到另一个奇怪的问题,在 system.applicationHost->applicationPools 下的 appPool 上设置 autoStart="true" 是另一台服务器上唯一需要的。

以上是关于IIS 7.5 中的 Windows 身份验证失败的主要内容,如果未能解决你的问题,请参考以下文章

使用 Silverlight 5、IIS 7.5 对 WCF 服务进行 Windows 身份验证

使用 Powershell 3.0 切换 IIS 7.5 身份验证“匿名身份验证”?

iis 7.5 dns windows身份验证页面用户身份不起作用

具有 Windows 身份验证的 IIS 7.5 Web 应用程序是不是要求最终用户具有文件权限?

密码保护 IIS 7.5 中的 ASP.NET Web 应用程序

MVC 5 IIS 7.5 双跳问题(避免硬编码 SQL 密码)