IIS 7.5中的Windows身份验证失败

26
我正在为公司构建一个简单的内部应用程序,需要使用Windows身份验证进行安全保护。所有其他身份验证模式都已禁用。我陷入了这样一种情况:Internet Explorer提示了3次凭据,然后出现以下错误:

未经授权

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

接着我创建了一个简单的网站来测试它。我在IIS中创建了一个新站点,将其放置在自己的端口(:8111,随机选择),在其中放置了一个静态的“default.htm”文件,禁用了匿名身份验证,然后启用了Windows身份验证。其他所有设置均保持默认设置。端口号被分配,因为我们在这台计算机上有多个站点共享同一个IP。
以下是几种情况:
  • 从Web服务器本身浏览,http://localhost:8111/可以正常工作

  • 从另一台计算机浏览,http://ServerIPaddress:8111/可以正常工作

  • 从另一台计算机浏览,http://ServerName:8111/失败(要求输入凭据3次,然后显示401错误)

我一直在网上搜索并尝试寻找解决方案,但一直没有成功。要么我还没有找到它,要么我对阅读的内容理解不够深刻。非常感谢任何帮助。
5个回答

47

在与这个问题奋斗了两天后,在同事的帮助下终于解决了。以下是他写的解决方案:

Windows身份验证有两种提供者(Negotiate和NTLM)。当将网站身份验证设置为Windows身份验证时, 在突出显示Windows身份验证的情况下,单击右侧窗格或IIS管理器中的Providers链接并将NTLM移动到顶部。 默认情况下,Negotiate处于顶部,这就是为什么会出现身份验证提示的原因。


1
+1,这对我来说很有效,虽然更深入和正确的答案是要查找为什么协商失败,但这确实快速地指出了问题所在。 - Seph
因此我浪费了半天的时间。感谢你修复了它。 - learnerplates
这对我也解决了。在我的情况下,我遇到了504网关超时错误。 - Justin Skiles
@seph - 我在下面发布了一个新的答案,其中引用了一个 msdn 文章,该文章显示了解决此问题以使用 Negotiate 的方法。 - mservidio
这似乎意味着有效协商意味着使用Kerberos,而Kerberos失败了。Kerberos很可能会失败,但如果我在提供程序中没有它,为什么要使用它?https://dev59.com/_2s05IYBdhLWcg3wR_23 - Nick.McDermaid
显示剩余3条评论

20

当您浏览使用集成身份验证的网站时出现错误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


谢谢!这对我有用,我从过去几个小时的开发者痛苦和挫败中解脱了出来。 - VolleyBall Player
谢谢您。我刚才看了一眼并看到了这个注册表编辑。当上述NTLM修复无效时,我建议这是明确的下一步。这验证了我花费在尝试解决这个问题上的许多工作小时! - JTester
这只会影响从托管网站的同一台机器上浏览时的Windows身份验证。 - Mick
这很危险。不要全局禁用回环检查...它存在是有原因的。 - Chase Florell
我曾经是一个SharePoint开发人员,每次构建开发服务器时都必须这样做...但是我已经进入MVC领域有一段时间了,完全忘记了,所以感谢您提醒我。 - Ryan Mann

6
如果在将NTML移到提供程序列表的顶部后仍然无法正常工作,请尝试完全删除Negotiate,只留下NTML。
这对我有用-将NTML移到顶部在Windows Server 2012和IIS 8.5上没有帮助。 我在以下stackoverflow问题中找到了解决方案:IIS 7.5 Windows Authentication Not Working in Chrome

5

我个人建议不要在服务器上全局禁用回环检查(即:不要将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


在内部开发服务器上禁用它不会带来任何风险。如果它是生产服务器,您可能会远程访问它,无论如何都可以保留回环。 - Ryan Mann
@Ryios,即使在开发中,推荐的方式也是按域进行而不是全局进行。在生产环境中,我们有许多应用程序(SOA)调用同一服务器上的其他应用程序。 - Chase Florell

2
这个问题已经有一段时间了,但我知道很多人经常遇到。更合适的解决方法在这里详细描述: 内核模式身份验证。我们几个月前就实施了这个方法,它运行良好。
另一个很好的解释在这里: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,但是它并没有解决问题。移除Negotiate确实解决了问题...但是为什么呢? - Nick.McDermaid
这绝对是我需要的修复。另外,我注意到在另一台服务器上,在system.applicationHost->applicationPools下设置autoStart="true"是唯一必要的事情,以解决另一个奇怪的问题。 - B Days

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接