When Windows Authentication fails in IIS 7.5 without even presenting a credential challenge (missing WWW-Authenticate headers), it typically indicates a fundamental breakdown in the authentication handshake process. The key symptom is receiving an immediate 401.2 error without any negotiation attempt.
From network traces, we observe the critical difference between working and failing scenarios:
// Working response (localhost) HTTP/1.1 401 Unauthorized WWW-Authenticate: Negotiate WWW-Authenticate: NTLM // Failing response (remote) HTTP/1.1 401 Unauthorized (No WWW-Authenticate headers)
First, confirm these essential settings in applicationHost.config:
<system.webServer> <security> <authentication> <windowsAuthentication enabled="true"> <providers> <add value="Negotiate" /> <add value="NTLM" /> </providers> </windowsAuthentication> </authentication> </security> </system.webServer>
These often-overlooked settings can prevent WWW-Authenticate headers:
- Kernel-mode authentication: Disable with
appcmd set config /section:windowsAuthentication /useKernelMode:false
- URLScan or Request Filtering: May block authentication headers
- Custom HTTP Modules: Can interfere with authentication flow
1. Check authentication provider order:
// PowerShell command to verify providers Get-WebConfigurationProperty -Filter "/system.webServer/security/authentication/windowsAuthentication/providers" -Name "." | Select-Object -ExpandProperty Collection
2. Verify SPN configuration (even in non-domain environments):
setspn -L <SERVERNAME>
Add these registry keys if missing:
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa] "DisableLoopbackCheck"=dword:00000001 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP\Parameters] "DisableNTLMPreAuth"=dword:00000000
For immediate resolution, force NTLM-only mode:
<system.webServer> <security> <authentication> <windowsAuthentication enabled="true"> <providers> <clear /> <add value="NTLM" /> </providers> </windowsAuthentication> </authentication> </security> </system.webServer>
After making changes, test with this PowerShell command to confirm headers are being sent:
Invoke-WebRequest -Uri http://yoursite.com -UseDefaultCredentials -Method HEAD -Headers @{"Authorization"="NTLM"} | Select-Object -ExpandProperty Headers
When Windows Authentication fails to present a credential challenge in IIS 7.5, the fundamental issue typically manifests as missing WWW-Authenticate
headers in the server response. This prevents the authentication handshake from initiating properly.
First, confirm these critical settings in applicationHost.config
(located in %windir%\system32\inetsrv\config
):
<location path="Default Web Site/YourApp"> <system.webServer> <security> <authentication> <windowsAuthentication enabled="true"> <providers> <add value="Negotiate" /> <add value="NTLM" /> </providers> </windowsAuthentication> <anonymousAuthentication enabled="false" /> </authentication> </security> </system.webServer> </location>
Several overlooked factors can suppress authentication headers:
- Double-Hop Restrictions: When the server isn't domain-joined, NTLM may fail silently
- Kernel-Mode Authentication: Check via
appcmd list config /section:windowsAuthentication
foruseKernelMode
- Authentication Module Order: Ensure WindowsAuth runs before AnonymousAuth in the pipeline
Run this to verify authentication module status:
Import-Module WebAdministration Get-WebConfigurationProperty -Filter "/system.webServer/security/authentication/windowsAuthentication" -Name Enabled Get-WebConfigurationProperty -Filter "/system.webServer/security/authentication/windowsAuthentication" -Name Providers Get-WebConfigurationProperty -Filter "/system.webServer/security/authentication/anonymousAuthentication" -Name Enabled
For stubborn cases, verify these registry settings (backup first!):
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\NTLM] "RestrictReceivingNTLMTraffic"=dword:00000000 "RestrictSendingNTLMTraffic"=dword:00000000
Sometimes the kernel-level HTTP listener needs adjustment:
netsh http show servicestate netsh http add iplisten ipaddress=::
When examining FREB logs, focus on these critical events:
AUTH_START
- Should show Windows Auth module initializationMODULE_SET_RESPONSE_ERROR_STATUS
- Check for hidden permission issuesGENERAL_RESPONSE_HEADERS
- Verify header generation phase
As a temporary measure, you can force headers via URL Rewrite:
<rewrite> <outboundRules> <rule name="Add WWW-Authenticate Headers" preCondition="Is401"> <match serverVariable="RESPONSE_WWW_Authenticate" pattern=".*" /> <action type="Rewrite" value="Negotiate, NTLM" /> </rule> <preConditions> <preCondition name="Is401"> <add input="{RESPONSE_STATUS}" pattern="^401" /> </preCondition> </preConditions> </outboundRules> </rewrite>