Windows身份validation在本地IIS 7.5上不起作用。 错误401.1

我最近有一个令人讨厌的问题,让Windows身份validation在IIS 7.5(Windows 7 Pro)的本地实例上运行到ASP.net 4.0站点。 我遵循了基本的步骤。

IIS身份validation

  • 禁用匿名身份validation
  • 启用Windows身份validation

编辑web.config

<authentication mode="Windows" /> 

这在启用Windows身份validation方面做得不错,但是每次尝试login都被拒绝,最终返回401.1错误。 这是问题出现的地方。 似乎有很多的理由,这是很好的文件在networking上,包括在这里堆栈溢出。

我试过了:

  • 编辑Windows身份validation的IIS身份validation“高级设置”以禁用扩展保护和内核模式身份validation
  • 编辑IIS身份validation“提供程序”以将NTLM移动到协商之上。
  • 编辑IIS .NET授权规则以显式允许用户(以及各种其他组合)。
  • 各种IIS命令行脚本和调整。
  • web.config文件中的各种configuration调整。
  • 甚至一些文件系统的权限调整。

但所有无济于事,可怕的401.1仍然存在。

这实际上是“看不见树木”的情况。 我找不到任何解决scheme(如果你愿意的话,将其称为一个不好的search参数),所以我认为值得发表这个问题,希望提供一个明确的答案,更容易find任何人遭受同样的问题。

这里的问题是,现代版本的Windows(Windows XP SP2,Windows server 2003 SP1及更高版本)包含一个环回检查安全功能,旨在帮助防止计算机上的反射攻击。 因此,如果使用的FQDN或自定义主机标头与本地计算机名称不匹配,身份验证将失败。

这可以通过显式指定主机名或禁用回送检查来解决。 显然前者是更受控制的方法。

  1. 将DisableStrictNameChecking注册表项设置为1.请参阅: 281308 (注意:我不需要这样做)
  2. 在注册表编辑器中找到并单击以下注册表项:HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control \ Lsa \ MSV1_0
  3. 用鼠标右键单击MSV1_0,指向新建,然后再单击多字符串值。
  4. 键入BackConnectionHostNames,然后按ENTER键。
  5. 用鼠标右键单击BackConnectionHostNames,然后单击修改。
  6. 在数值数据框中,键入本地计算机上的站点的主机名或主机名,然后单击确定。
  7. 退出注册表编辑器,然后重新启动IISAdmin服务。

如何做到这一点的详细信息可以在MSDN上找到: 896861

希望这可以帮助别人。 如果您有任何其他建议或改进,请添加。

我想添加迈克尔·黑的评论作为答案,因为我没有权限来修改我的注册表,皮特的答案不适合我,但我能够解决这个问题。

我通过添加一个新的绑定到我的网站没有指定的主机名和不同的端口(因为localhost:80用于我)解决了它。 只要我尝试从http:// localhost:86 / mypage调用它,它的工作。 在浏览器中快速检查后,我用cURL测试了几次,并正确接受并拒绝了我的凭证。

重新安装您的IIS功能,并确保WINDOWS auth复选框statys选中。

这里是我用来处理反向连接主机名和IIS的PowerShell代码。 请注意,通过一些工作,可以将这些命令行程序保存到模块中并以此方式使用。

 Import-modulee WebAdministration function Add-BackConnectionHostname { <# .SYNOPSIS Adds the back connection hostnames that will bypass the server loopback check. .DESCRIPTION Adds the hostname to the list of back connection hostnames that will bypass the server loopback check. Back connection host names can be used to address the problem with IIS sites using Windows Authentication that is described in Microsoft KB896861. .EXAMPLE Add-BackConnectionHostname mywebsite.mydomain.tld .EXAMPLE Add-BackConnectionHostname mywebsite1.mydomain.tld, mywebsite2.mydomain.tld .PARAMETER Hostname The Hostname to add to the back connection hostnames list. .LINK Remove-BackConnectionHostname Get-BackConnectionHostname Enable-serverLoopbackCheck Disable-serverLoopbackCheck Get-serverLoopbackCheck "You receive error 401.1 when you browse a Web site that uses Integrated Authentication and is hosted on IIS 5.1 or a later version" (http://support.microsoft.com/en-us/kb/896861) #> [CmdletBinding(SupportsShouldProcess = $true)] param ( [Parameter(ValueFromPipeline = $true, Mandatory = $true)] [string] $Hostname ) begin { $keyPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" $propertyName = "BackConnectionHostnames" $key = Get-Item $keyPath $property = $null $propertyValues = $null if ($key -ne $null) { $property = Get-ItemProperty $keyPath -Name $propertyName -ErrorAction SilentlyContinue if ($property -eq $null) { $property = New-ItemProperty $keyPath -Name $propertyName -Value $null -PropertyType ([Microsoft.Win32.RegistryValueKind]::MultiString) -ErrorAction Stop Write-Verbose "Created the $($propertyName) property." } if ($property -ne $null) { $propertyValues = $property.$propertyName } } } process { if ($property -ne $null) { foreach ($hostNameValue in $Hostname) { if ([string]::IsNullOrWhiteSpace($hostName) -eq $false -and $propertyValues -notcontains $hostNameValue) { $propertyValues += $hostNameValue Write-Verbose "Added $($hostName) to the back connection hostnames." } else { Write-Verbose "Back connection host names already has an entry for $($hostName)." } } } } end { if ($propertyValues -ne $null) { $propertyValues = $propertyValues | ?{ [string]::IsNullOrWhiteSpace($_) -eq $false } | Sort -Unique Set-ItemProperty $keyPath -Name $propertyName -Value $propertyValues } } } function Remove-BackConnectionHostname { <# .SYNOPSIS Removes the hostname from the list of back connection hostnames that will bypass the server loopback check. .DESCRIPTION Removes the hostname from the list of back connection hostnames that will bypass the server loopback check. .EXAMPLE Remove-BackConnectionHostname mywebsite.mydomain.tld .EXAMPLE Remove-BackConnectionHostname mywebsite1.mydomain.tld, mywebsite2.mydomain.tld .PARAMETER Hostname The Hostname to remove from the back connection hostnames list. .LINK Add-BackConnectionHostname Get-BackConnectionHostname Enable-serverLoopbackCheck Disable-serverLoopbackCheck Get-serverLoopbackCheck "You receive error 401.1 when you browse a Web site that uses Integrated Authentication and is hosted on IIS 5.1 or a later version" (http://support.microsoft.com/en-us/kb/896861) #> [CmdletBinding(SupportsShouldProcess = $true)] param ( [Parameter(ValueFromPipeline = $true, Mandatory = $true)] [string] $Hostname ) begin { $keyPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" $propertyName = "BackConnectionHostnames" $key = Get-Item $keyPath $property = $null $propertyValues = $null if ($key -ne $null) { $property = Get-ItemProperty $keyPath -Name $propertyName -ErrorAction SilentlyContinue if ($property -ne $null) { $propertyValues = $property.$propertyName } else { Write-Verbose "The $($propertyName) property was not found." } } } process { if ($property -ne $null) { foreach ($hostNameValue in $Hostname) { if ($propertyValues -contains $hostNameValue) { $propertyValues = $propertyValues | ? { $_ -ne $hostName } Write-Verbose "Removed $($hostName) from the $($propertyName) property." } else { Write-Verbose "No entry for $($hostName) was found in the $($propertyName) property." } } } } end { if ($property -ne $null) { $propertyValues = $propertyValues | ?{ [string]::IsNullOrWhiteSpace($_) -eq $false } | Sort -Unique if ($propertyValues.Length -ne 0) { Set-ItemProperty $keyPath -Name $propertyName -Value $propertyValues } else { Remove-ItemProperty $keyPath -Name $propertyName Write-Verbose "No entries remain after removing $($hostName). The $($propertyName) property was removed." } } } } function Get-BackConnectionHostname { <# .SYNOPSIS Gets the list of back connection hostnames that will bypass the server loopback check. .DESCRIPTION Gets the back connection hostnames that will bypass the server loopback check. Back connection host names can be used to address the problem with IIS sites using Windows Authentication that is described in Microsoft KB896861. .EXAMPLE Get-BackConnectionHostname .LINK Add-BackConnectionHostname Remove-BackConnectionHostname Enable-serverLoopbackCheck Disable-serverLoopbackCheck Get-serverLoopbackCheck "You receive error 401.1 when you browse a Web site that uses Integrated Authentication and is hosted on IIS 5.1 or a later version" (http://support.microsoft.com/en-us/kb/896861) #> [CmdletBinding(SupportsShouldProcess = $false)] param ( ) begin { $keyPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" $propertyName = "BackConnectionHostnames" $key = Get-Item $keyPath $property = $null if ($key -ne $null) { $property = Get-ItemProperty $keyPath -Name $propertyName -ErrorAction SilentlyContinue if ($property -eq $null) { Write-Verbose "The $($propertyName) property was not found." } } } process { $propertyValues = $null if ($property -ne $null) { $propertyValues = $property.$propertyName } return $propertyValues } end { } } function Enable-serverLoopbackCheck { <# .SYNOPSIS Enables the server loopback check. Enabled is the normal state for a Windows server. .DESCRIPTION Enables the server loopback check. Having the loopback check enabled is the normal state for a Windows server. Disabling the loopback check can be used to address the problem with IIS sites using Windows Authentication that is described in Microsoft KB896861. It is NOT the preferred method. See the KB article for more details. .EXAMPLE Enable-serverLoopbackCheck .LINK Add-BackConnectionHostname Remove-BackConnectionHostname Get-BackConnectionHostname Enable-serverLoopbackCheck Get-serverLoopbackCheck "You receive error 401.1 when you browse a Web site that uses Integrated Authentication and is hosted on IIS 5.1 or a later version" (http://support.microsoft.com/en-us/kb/896861) #> [CmdletBinding(SupportsShouldProcess = $true)] param ( ) begin { $keyPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" $propertyName = "DisableLoopbackCheck" $key = Get-Item $keyPath $property = $null if ($key -ne $null) { $property = Get-ItemProperty $keyPath -Name $propertyName -ErrorAction SilentlyContinue if ($property -eq $null) { Write-Verbose "The $($propertyName) property was not found." } } } process { if ($property -ne $null) { Set-ItemProperty $keyPath -Name $propertyName -Value 0 } } end { } } function Disable-serverLoopbackCheck { <# .SYNOPSIS Disables the server loopback check for all hostnames. Enabled is the normal state for a Windows server. .DESCRIPTION Disables the server loopback check for all hostnames. Having the loopback check enabled is the normal state for a Windows server. Disabling the loopback check can be used to address the problem with IIS sites using Windows Authentication that is described in Microsoft KB896861. It is NOT the preferred method. See the KB article for more details. .EXAMPLE Disable-serverLoopbackCheck .LINK Add-BackConnectionHostname Remove-BackConnectionHostname Get-BackConnectionHostname Enable-serverLoopbackCheck Get-serverLoopbackCheck "You receive error 401.1 when you browse a Web site that uses Integrated Authentication and is hosted on IIS 5.1 or a later version" (http://support.microsoft.com/en-us/kb/896861) #> [CmdletBinding(SupportsShouldProcess = $true)] param ( ) begin { $keyPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" $propertyName = "DisableLoopbackCheck" $key = Get-Item $keyPath $property = $null if ($key -ne $null) { $property = Get-ItemProperty $keyPath -Name $propertyName -ErrorAction SilentlyContinue if ($property -eq $null) { Write-Verbose "The $($propertyName) property was not found." } } } process { if ($property -ne $null) { Set-ItemProperty $keyPath -Name $propertyName -Value 1 } else { $property = New-ItemProperty $keyPath -Name $propertyName -PropertyType ([Microsoft.Win32.RegistryValueKind]::DWord) -Value 1 } } end { } } function Get-serverLoopbackCheck { <# .SYNOPSIS Gets the status of the server loopback check. Enabled is the normal state for a Windows server. .DESCRIPTION Gets the status of the server loopback check. Having the loopback check enabled is the normal state for a Windows server. Disabling the loopback check can be used to address the problem with IIS sites using Windows Authentication that is described in Microsoft KB896861. It is NOT the preferred method. See the KB article for more details. .EXAMPLE Get-serverLoopbackCheck .LINK Add-BackConnectionHostname Remove-BackConnectionHostname Get-BackConnectionHostname Enable-serverLoopbackCheck Disable-serverLoopbackCheck "You receive error 401.1 when you browse a Web site that uses Integrated Authentication and is hosted on IIS 5.1 or a later version" (http://support.microsoft.com/en-us/kb/896861) #> [CmdletBinding(SupportsShouldProcess = $false)] param ( ) begin { $keyPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" $propertyName = "DisableLoopbackCheck" $key = Get-Item $keyPath $property = $null if ($key -ne $null) { $property = Get-ItemProperty $keyPath -Name $propertyName -ErrorAction SilentlyContinue } } process { $loopbackCheckStatus = "Enabled" if ($property -ne $null) { switch ($property) { 0 { $loopbackCheckStatus = "Enabled" } 1 { $loopbackCheckStatus = "Disabled" } default { $loopbackCheckStatus = "Unknown" } } } return $loopbackCheckStatus } end { } } function Get-WebsiteHostname { <# .SYNOPSIS Gets the hostnames for the IP addresses bound to a web site. .DESCRIPTION Gets the hostnames for the IP addresses bound to a web site. Where a host header exists, the host header is used; otherwise, the IP address is looked up in DNS to see if a PTR record exists. .EXAMPLE Get-WebSiteHostname $webSite .EXAMPLE Get-WebSiteHostname -Name 'Default Web Site' .EXAMPLE Get-Website | Get-WebSiteHostname .LINK Get-Website #> [CmdletBinding(SupportsShouldProcess = $false)] param ( [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Mandatory = $true)] [string] $Name ) process { $siteHostnames = @() foreach ($webSiteName in $Name) { $bindings = Get-WebBinding -Name $Name foreach ($binding in $bindings) { $bindingInfo = $binding.bindingInformation.Split(':') $hostHeader = $bindingInfo[2] $bindingInfoAddress = $null $isValidIP = [System.Net.IPAddress]::TryParse($bindingInfo[0], [ref] $bindingInfoAddress) $siteHostname = $null if ($bindingInfo -eq '*') { Write-Warning "The $($webSiteName) web site has a binding address set to All Unassigned." } elseif ([string]::IsNullOrWhiteSpace($hostHeader) -eq $false) { $siteHostname = $hostHeader Write-Verbose "The $($webSiteName) web site has a host header set to $($siteHostname)." } elseif ($isValidIP -eq $true) { $siteHostname = (Resolve-DnsName $bindingInfoAddress -DnsOnly PTR -ErrorAction SilentlyContinue).NameHost if ($siteHostname -ne $null) { Write-Verbose "The $($webSiteName) web site has an IP Address $($bindingInfoAddress) that resolves to $($siteHostname)." } else { Write-Warning "The $($webSiteName) web site has an IP Address $($bindingInfoAddress) with no PTR record." } } } if ($siteHostname -ne $null) { $siteHostnames += $siteHostname } } return $siteHostnames | Sort -Unique } } Get-Website | ?{ (Get-WebConfiguration -Filter '/system.web/authentication' -PSPath $_.PSPath).mode -eq 'Windows' } | Get-WebsiteHostname | Add-BackConnectionHostname