Introduction to IIS Authentication on Windows Server 2019
IIS 10 on Windows Server 2019 supports multiple authentication mechanisms, each suitable for different scenarios. Anonymous Authentication allows unauthenticated access (public websites). Windows Authentication uses Kerberos or NTLM to authenticate domain users transparently (intranet applications). Basic Authentication sends credentials in Base64 (requires HTTPS). Digest Authentication uses MD5 hashing. Forms Authentication is handled by the application layer. Client Certificate Authentication uses X.509 certificates. This guide covers configuring each authentication type, layering multiple mechanisms, and securing the authentication configuration.
Authentication Module Prerequisites
# Install authentication feature modules
Install-WindowsFeature `
-Name Web-Server, `
Web-Windows-Auth, `
Web-Basic-Auth, `
Web-Digest-Auth, `
Web-Client-Auth, `
Web-IP-Security `
-IncludeManagementTools
# Verify installed authentication features
Get-WindowsFeature -Name Web-*-Auth | Where-Object InstallState -eq Installed |
Select-Object Name, DisplayName | Format-Table
Configure Anonymous Authentication
Anonymous Authentication is enabled by default and uses the IUSR built-in account. For security, change the anonymous user identity to the Application Pool Identity so file system access is controlled per-pool rather than shared across all sites:
# Check current anonymous authentication configuration
Get-WebConfiguration -Filter "system.webServer/security/authentication/anonymousAuthentication" `
-PSPath "IIS:SitesDefault Web Site"
# Disable anonymous authentication on the site (force authentication)
Set-WebConfigurationProperty `
-PSPath "IIS:SitesMyIntranetSite" `
-Filter "system.webServer/security/authentication/anonymousAuthentication" `
-Name "enabled" -Value $false
# Change anonymous user identity to AppPoolIdentity (recommended)
Set-WebConfigurationProperty `
-PSPath "IIS:SitesDefault Web Site" `
-Filter "system.webServer/security/authentication/anonymousAuthentication" `
-Name "userName" -Value "" # Empty = use ApplicationPoolIdentity
Configure Windows Authentication (Kerberos/NTLM)
Windows Authentication is ideal for intranet applications where all users are on the domain. Kerberos is the preferred provider because it does not expose password hashes and supports mutual authentication. NTLM is used as a fallback when Kerberos is unavailable (e.g., when accessing by IP address or cross-forest without trust).
# Enable Windows Authentication
Set-WebConfigurationProperty `
-PSPath "IIS:SitesMyIntranetSite" `
-Filter "system.webServer/security/authentication/windowsAuthentication" `
-Name "enabled" -Value $true
# Disable Anonymous Authentication (require Windows auth)
Set-WebConfigurationProperty `
-PSPath "IIS:SitesMyIntranetSite" `
-Filter "system.webServer/security/authentication/anonymousAuthentication" `
-Name "enabled" -Value $false
# Set Kerberos first, then NTLM as fallback
Set-WebConfigurationProperty `
-PSPath "IIS:SitesMyIntranetSite" `
-Filter "system.webServer/security/authentication/windowsAuthentication" `
-Name "providers" -Value @{value="Negotiate","NTLM"}
# Disable kernel-mode authentication (needed for some delegation scenarios)
Set-WebConfigurationProperty `
-PSPath "IIS:SitesMyIntranetSite" `
-Filter "system.webServer/security/authentication/windowsAuthentication" `
-Name "useKernelMode" -Value $true # $true is default and preferred
# Verify
Get-WebConfigurationProperty `
-PSPath "IIS:SitesMyIntranetSite" `
-Filter "system.webServer/security/authentication/windowsAuthentication" `
-Name "*"
Configure Kerberos SPN for Custom Application Pool Identities
When using a custom service account (not ApplicationPoolIdentity) with Windows Authentication, you must register a Service Principal Name (SPN) for the account or Kerberos negotiation will fall back to NTLM:
# Register SPN for the service account running the application pool
# Format: HTTP/hostname and HTTP/fqdn
setspn -S HTTP/myintranet corpsvc-webapp
setspn -S HTTP/myintranet.corp.example.com corpsvc-webapp
# Verify SPNs
setspn -L corpsvc-webapp
# Enable constrained delegation for the service account (if app accesses backend services)
Set-ADUser -Identity "svc-webapp" `
-TrustedForDelegation $false # Never use unconstrained delegation
# Use Get-ADComputer/Set-ADUser with PrincipalsAllowedToDelegateToAccount for constrained
Configure Basic Authentication
Basic Authentication must always be used over HTTPS, as credentials are Base64 encoded (not encrypted). Suitable for REST APIs accessed by non-browser clients:
# Enable Basic Authentication
Set-WebConfigurationProperty `
-PSPath "IIS:SitesMyAPIsite" `
-Filter "system.webServer/security/authentication/basicAuthentication" `
-Name "enabled" -Value $true
# Set the default domain for Basic Auth (clients that don't send domain)
Set-WebConfigurationProperty `
-PSPath "IIS:SitesMyAPIsite" `
-Filter "system.webServer/security/authentication/basicAuthentication" `
-Name "defaultLogonDomain" -Value "corp"
# Disable Anonymous Authentication
Set-WebConfigurationProperty `
-PSPath "IIS:SitesMyAPIsite" `
-Filter "system.webServer/security/authentication/anonymousAuthentication" `
-Name "enabled" -Value $false
# Enforce HTTPS-only access (prevents Basic Auth over HTTP)
Add-WebConfigurationProperty `
-PSPath "IIS:SitesMyAPIsite" `
-Filter "system.webServer/security/access" `
-Name "sslFlags" -Value "Ssl"
Configure Client Certificate Authentication
Client Certificate Authentication requires clients to present a valid X.509 certificate issued by a trusted CA. This provides mutual TLS authentication — the server proves its identity to the client (standard TLS) and the client proves its identity to the server (mutual TLS):
# Install Client Certificate Authentication feature
Install-WindowsFeature -Name Web-Client-Auth
# Require client certificates on the site (Require mode)
Set-WebConfigurationProperty `
-PSPath "IIS:SitesMySecureSite" `
-Filter "system.webServer/security/access" `
-Name "sslFlags" -Value "Ssl,SslNegotiateCert,SslRequireCert"
# Ssl = require SSL, SslNegotiateCert = request cert, SslRequireCert = require cert
# Enable IIS Client Certificate Mapping Authentication
Set-WebConfigurationProperty `
-PSPath "IIS:SitesMySecureSite" `
-Filter "system.webServer/security/authentication/iisClientCertificateMappingAuthentication" `
-Name "enabled" -Value $true
# Add trusted CA to IIS (certificate must be in LocalMachineCA or Root store)
$caCert = Get-ChildItem Cert:LocalMachineRoot |
Where-Object Subject -match "Corp Internal CA"
Write-Host "CA Thumbprint: $($caCert.Thumbprint)"
Configure IP Address and Domain Restrictions
Layer IP-based access control on top of authentication to restrict which networks can even attempt authentication:
# Install IP Security feature
Install-WindowsFeature -Name Web-IP-Security
# Allow only internal subnet, deny all others
Add-WebConfigurationProperty `
-PSPath "IIS:SitesMyIntranetSite" `
-Filter "system.webServer/security/ipSecurity" `
-Name "." `
-Value @{ipAddress="192.168.0.0"; subnetMask="255.255.0.0"; allowed="True"}
Set-WebConfigurationProperty `
-PSPath "IIS:SitesMyIntranetSite" `
-Filter "system.webServer/security/ipSecurity" `
-Name "allowUnlisted" -Value $false # Deny all not explicitly allowed
Verify Authentication Configuration
# Check all authentication providers for a site
Get-WebConfiguration -Filter "system.webServer/security/authentication/*" `
-PSPath "IIS:SitesMyIntranetSite" |
Select-Object PSChildName,
@{n="Enabled";e={$_.enabled}} | Format-Table
# Test Windows Authentication with PowerShell WebRequest
$cred = Get-Credential
Invoke-WebRequest -Uri "http://myintranet.corp.example.com/api/test" `
-Credential $cred -UseDefaultCredentials
Summary
IIS authentication on Windows Server 2019 provides a layered security model. Anonymous Authentication is appropriate for public content but should be switched to ApplicationPoolIdentity. Windows Authentication with Kerberos as the primary provider is best for domain-joined intranet users. Basic Authentication is suitable for APIs but must be enforced over HTTPS. Client Certificate Authentication provides the strongest authentication assurance for sensitive systems. Combining authentication with IP address restrictions adds defence-in-depth beyond credential verification alone.