【问题标题】:Windows Authentication not working on local IIS 7.5. Error 401.1Windows 身份验证在本地 IIS 7.5 上不起作用。错误 401.1
【发布时间】:2013-07-04 09:26:46
【问题描述】:

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

IIS 身份验证

  • 禁用匿名身份验证
  • 启用 Windows 身份验证

编辑 web.config

<authentication mode="Windows" />

这在启用 Windows 身份验证方面做得很好,但每次登录尝试都被拒绝并最终返回 401.1 错误。这就是问题开始的地方。这似乎有很多原因,这些原因在网络上都有很好的记录,包括在 Stack Overflow 上。

我试过了:

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

但一切都无济于事,可怕的 401.1 仍然存在。

这真是一个“见树不见林”的案例。我设法找到的所有解决方案(如果你愿意,可以称之为错误搜索参数的情况)对我有用,所以我认为值得发布这个问题,希望能提供一个明确的答案,让遇到同样问题的人更容易找到.

【问题讨论】:

    标签: c# asp.net windows iis windows-authentication


    【解决方案1】:

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

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

    1. 将 DisableStrictNameChecking 注册表项设置为 1。请参阅:281308 (注意:对于 Windows Server 2008/Vista 及更高版本,这应该是不必要的)
    2. 在注册表编辑器中,找到并单击以下注册表项: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0
    3. 右键单击 MSV1_0,指向新建,然后单击多字符串值。
    4. 键入 BackConnectionHostNames,然后按 Enter。
    5. 右键单击 BackConnectionHostNames,然后单击修改。
    6. 在“数值数据”框中,键入本地计算机上站点的一个或多个主机名,然后单击“确定”。
    7. 退出注册表编辑器,然后重新启动 IISAdmin 服务。

    可以在 MSDN 上找到有关如何执行此操作的完整详细信息:896861

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

    【讨论】:

    • 就我而言,它就像使用localhost 而不是foobar.com 地址一样简单。感谢您为我指明这个方向。
    • 不幸的是,这对我也不起作用。我的问题是模式登录窗口不断出现。
    • 我能够通过在 IIS 中添加绑定并使用主机名作为我的机器名称来解决问题。这为我解决了问题。
    • @JoeyStallmeyer - 可能是站点文件夹权限问题,因为此解决方案绝对解决了问题
    • 解决方案适用于添加 DNS 条目的情况,并且可以使用 FQDN 从工作站访问站点,但当主机名无法从服务器本身访问时您添加到 DNS 的名称与服务器的机器名称不同。很好地参考了 MS 支持文章。将其归档在我的知识库中,因为我确定我会再次需要它。另外,请注意 - MS 文章 281308 说在编辑注册表后重新启动,但在完成编辑和 MSV1_0 键编辑之后,我刚刚重新启动了 IIS 管理服务,它在没有重新启动的情况下运行良好。获得 1 个身份验证提示并进入。
    【解决方案2】:

    我想添加 Michael Dark 的评论作为答案,因为我没有修改注册表的权限,所以 Pete 的答案对我不起作用,但我能够解决问题。

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

    【讨论】:

    • 这实际上也对我有用。甚至没有考虑更改主机绑定,但是当我这样做时,它立即起作用。有什么想法是什么原因造成的吗?
    • 没关系上面的问题。我尝试了 PeteWifi 的解决方案,效果也很好。
    【解决方案3】:

    再次重新安装 IIS 功能并确保选中 WINDOWS auth 复选框状态。

    【讨论】:

      【解决方案4】:

      这是我用来处理反向连接主机名和 IIS 的 PowerShell 代码。请注意,只需做一些工作,就可以将命令行开关保存到一个模块中并以这种方式使用。

      Import-Module 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-23
        • 1970-01-01
        • 2013-07-30
        • 2016-01-26
        • 1970-01-01
        • 2022-01-25
        • 2012-09-23
        • 1970-01-01
        相关资源
        最近更新 更多