Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IIS Binding with windows authentication

I have a local website (http://localhost/testsite) with Windows Authentication, that works well.

Now I changed the binding of the site to an URL (http://testsite.blablabla.biz) with Windows Authentication which leads to an HTTP 401.1 - Unauthorized You do not have permission to view this directory or page using the credentials that you supplied error.

What am I doing wrong? I searched already a lot on google, but nothing really helps. I think it has something to do with domain names or something, but I'm not sure.

like image 742
Jordy Avatar asked Mar 03 '11 12:03

Jordy


People also ask

Does IIS use Windows Authentication?

The default installation of IIS 7 and later does not include the Windows authentication role service. To use Windows authentication on IIS, you must install the role service, disable Anonymous authentication for your Web site or application, and then enable Windows authentication for the site or application.

How does Windows Authentication work in IIS?

Authentication: The client generates and hashes a response and sends it to the IIS server. The server receives the challenge-hashed response and compares it to what it knows to be the appropriate response. If the received response matches the expected response, the user is successfully authenticated to the server.


2 Answers

Windows has a security feature for doing loopback checks, which is designed to help prevent reflection attacks on your computer.

When you use a custom host header to browse a local web site that is hosted on a computer running IIS you will receive this error message if the web site uses Windows authentication and has a name that is mapped to the local loopback address.

There are two methods to work around this issue:

  1. Disable the loopback check (not recommended), or
  2. Specify host names:

Using regedit, go to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0 and create key BackConnectionHostNames with type REG_MULTI_SZ. Populate the key with the FQDN(s) that need to use Windows Authentication on the local machine. No reboot is necessary.

Microsoft KB Article ID: 896861

like image 183
user731569 Avatar answered Oct 03 '22 03:10

user731569


Here are the PowerShell commandlets that I wrote to manage the loopback check settings. It includes code that attempts to get the hostnames for all IIS web sites that use Windows Authentication and sets the back connection host names.

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
    }
}

# Use the IIS administration commandlets and the ones above to do the 
# following:
#   1. Get all the IIS web sites that use Windows authentication.
#   2. Get the hostnames from either the host header setting or the
#      DNS reverse lookup of the hostnames from the IP address.
#   3. Add the hostnames to the BackConnectionHostNames registry key.
#   4. Display the contents of the BackConnectionHostNames registry key.

$windowsAuthenticatedWebSites = Get-Website | ?{ (Get-WebConfiguration -Filter '/system.web/authentication' -PSPath $_.PSPath).mode -eq 'Windows' }
$webSiteHostnames = $windowsAuthenticatedWebSites | Get-WebsiteHostname
$webSiteHostNames | Add-BackConnectionHostName

Get-BackConnectionHostName
like image 37
JamieSee Avatar answered Oct 03 '22 01:10

JamieSee