codememo

로컬 IIS 7.5에서 Windows 인증이 작동하지 않습니다. 오류 401.1

tipmemo 2023. 10. 10. 20:24
반응형

로컬 IIS 7.5에서 Windows 인증이 작동하지 않습니다. 오류 401.1

최근 IIS 7.5(Windows 7 Pro)의 로컬 인스턴스에서 ASP.net 4.0 사이트로 Windows 인증을 작동시키는 데 심각한 문제가 있었습니다.저는 기본적인 절차를 밟았습니다.

IIS 인증

  • 익명 인증확인 사용 안 함
  • Windows 인증 사용

web.config 편집

<authentication mode="Windows" />

이것은 윈도우 인증을 사용할 수 있게 해주었지만 로그인을 시도할 때마다 거부되어 결국 401.1 오류를 반환했습니다.여기서 문제가 시작되었습니다.여기 스택 오버플로를 포함하여 웹에서 잘 문서화된 여러 가지 이유가 있는 것 같습니다.

노력했습니다.

  • Windows 인증에 대한 IIS 인증 '고급 설정'을 편집하여 확장 보호 및 커널 모드 인증 사용 안 함
  • IIS 인증 '제공자'를 편집하여 NTLM을 협상 위로 이동합니다.
  • IIS 편집 중.NET Authorization Rules to explicit 사용자(및 기타 다양한 조합) 허용.
  • 다양한 IIS 명령줄 스크립트 및 변경
  • web.config 파일의 다양한 구성 변경.
  • 심지어 일부 파일 시스템 권한도 조정됩니다.

하지만 모두 실패했습니다. 무서운 401.1은 여전히 남아 있었습니다.

이것은 정말로 "나무를 위해 나무를 볼 수 없다"는 경우입니다.제가 발견한 어떤 해결책도 효과가 없었기 때문에(원한다면 잘못된 검색 매개 변수의 경우라고 부르십시오), 저는 같은 문제를 겪고 있는 사람들에게 더 쉽게 찾을 수 있는 명확한 답을 제공하기 위해 이 질문을 게시할 가치가 있다고 생각했습니다.

문제는 최신 버전의 Windows(Windows XP SP2, Windows Server 2003 SP1 이상)에 컴퓨터에 대한 반사 공격을 방지하도록 설계된 루프백 체크 보안 기능이 포함되어 있다는 것입니다.따라서 사용하는 FQDN 또는 사용자 지정 호스트 헤더가 로컬 시스템 이름과 일치하지 않으면 인증이 실패합니다.

이 문제는 호스트 이름을 명시적으로 지정하거나 루프백 검사를 사용하지 않도록 설정하여 해결할 수 있습니다.분명히 전자가 더 통제적인 접근 방식입니다.

  1. DisableStrictNameChecking 레지스트리 항목을 1로 설정합니다.참조: 281308 (참고: Windows Server 2008/Vista 이상에서는 이 작업이 불필요합니다.)
  2. 레지스트리 편집기에서 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Lsa\의 레지스트리 키를 찾은 다음 누르십시오.MSV1_0
  3. MSV1_0을 마우스 오른쪽 단추로 클릭하고 새로 만들기를 가리킨 다음 다중 문자열 값을 클릭합니다.
  4. 뒤로 연결 유형HostNames(호스트 이름)을 누른 다음 Enter(엔터)를 누릅니다.
  5. 연결 뒤로 마우스 오른쪽 버튼HostNames를 클릭한 다음 Modify를 클릭합니다.
  6. 값 데이터 상자에 로컬 시스템에 있는 사이트의 호스트 이름 또는 호스트 이름을 입력한 다음 확인을 누르십시오.
  7. 레지스트리 편집기를 종료한 다음 IISAdmin 서비스를 다시 시작합니다.

이 방법에 대한 자세한 내용은 MSDN: 896861에서 확인할 수 있습니다.

누군가에게 도움이 되길 바랍니다.대체 제안이나 개선 사항이 있으면 추가해 주시기 바랍니다.

제가 레지스트리를 수정할 수 있는 권한이 없어서 피트의 답변은 안 되지만 문제를 해결할 수 있었기 때문에 마이클 다크의 의견을 답변으로 추가하고 싶습니다.

지정된 호스트 이름과 다른 포트가 없는 새로운 바인딩을 웹 사이트에 추가하여 해결했습니다(localhost:80이 저에게 사용되므로).http://localhost:86/mypage에서 호출을 시도하는 순간 작동했습니다.브라우저에서 빠르게 체크한 후 cURL로 몇 번 테스트를 했는데 cURL이 제 자격 증명을 올바르게 승인하고 거부했습니다.

IIS 기능을 다시 설치하고 Windows auth 확인란 상태를 확인합니다.

백 연결 호스트 이름 및 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

언급URL : https://stackoverflow.com/questions/17466665/windows-authentication-not-working-on-local-iis-7-5-error-401-1

반응형