Authentication & Authorization: Windows Auth, Request Filtering & IP Restrictions
IIS In Depth
Chapter 8 · Authentication & Authorization: Windows Auth, Request Filtering & IP Restrictions
Web Servers Fundamentals Chapter 8 named IP/Domain Restrictions and Basic/Windows Authentication, without real directive depth. This chapter goes deep on all three — and Windows Authentication in particular has two genuine operational gotchas (a Kerberos SPN requirement, and the "double-hop" problem) that catch real deployments often enough to be worth understanding before they show up as a confusing, intermittent failure in production.
Windows Authentication: Two Providers, Not One
Negotiate attempts Kerberos first, falling back to NTLM only if Kerberos isn't available. NTLM is a genuinely older, weaker challenge-response protocol with no support for delegation (below) and no mutual authentication of the server to the client. Listing both providers, with Negotiate first, is the modern default — but the fallback to NTLM is silent and easy to miss, which is exactly what makes the SPN gotcha below so confusing when it happens.
This section lives under system.webServer/security/authentication — the same parent path as the windowsAuthentication element Chapter 3 used as its own overrideModeDefault="Deny" example. That's not a coincidence: authentication is exactly the kind of security-sensitive section that ships locked to applicationHost.config by default, and enabling Windows Authentication for a specific site or application generally requires either a machine-level change or a <location> override — not a change from that application's own web.config.
The SPN Gotcha: "It Works by IP but Fails by Hostname"
Kerberos requires a Service Principal Name (SPN) registered in Active Directory for the exact hostname the client is using to reach the site, bound to the account the Application Pool runs under:
Without a matching SPN, Kerberos authentication for that specific hostname fails — and because Negotiate silently falls back to NTLM, the site keeps working, just under the weaker protocol, with no obvious error telling anyone Kerberos never actually succeeded. This produces a real, genuinely confusing pattern: the site "works" when accessed by the server's raw machine name or IP address (where a default SPN often already exists), but a custom public hostname added later — exactly the kind Chapter 5's virtual directories and Chapter 7's SNI bindings both deal with routinely — was never registered, so Kerberos quietly fails for it while NTLM masks the failure entirely.
The Double-Hop Problem
Windows Authentication happily identifies who's making the request to IIS itself — but by default, that identity cannot be forwarded a second hop, to a separate backend server the application then needs to call (a SQL Server on its own machine, a separate API server). NTLM has no delegation mechanism at all. Kerberos can support delegation, but only if explicitly configured — the Application Pool's identity account needs to be trusted for delegation in Active Directory, and the target service needs its own registered SPN as well. Without that explicit configuration, a call to the second server either fails authentication entirely or silently falls back to the Application Pool's own service identity rather than the original user's — a distinction that matters a great deal if the second server's own access control was meant to be based on the actual end user, not on the web application's service account.
Request Filtering: A Native Pre-Handler Defense Layer
Request Filtering is a native module (Chapter 4) hooking one of the earliest pipeline events, rejecting a request outright before any handler or authentication module ever runs against it. requestLimits caps request-body size, total URL length, and query-string length — a genuine defense against oversized-upload abuse and certain buffer-related exploits, independent of anything the application code itself does. fileExtensions denies requests for specific extensions outright — .config here, so a misconfigured static-file handler can never accidentally serve a web.config's own contents to a visitor. hiddenSegments denies any request whose path contains a named segment anywhere — bin here, so /app/bin/secret.dll is blocked regardless of what physically exists there, since compiled application binaries have no legitimate reason to ever be served as a direct HTTP response.
IP and Domain Restrictions: Evaluation Order Matters
allowUnlisted sets the default action for any client IP that matches none of the explicit entries — false here means deny-by-default, an allowlist model. Individual entries are evaluated most-specific-match-wins, not strictly top-to-bottom: a single-IP rule (203.0.113.50, denied) takes precedence over a broader subnet rule that also happens to contain it (203.0.113.0/24, allowed) — letting one specific address be carved out as an exception to an otherwise-allowed range, or vice versa, without needing the entries listed in any particular order.
Hands-On Exercises
A site using Windows Authentication with the Negotiate provider works fine when accessed via the server's raw machine name, but authentication behaves oddly when accessed via a new public hostname added last week. Using this chapter's own material, explain the most likely cause and the command that would confirm/fix it.
📄 View solutionAn ASP.NET application authenticates users with Windows Authentication, then tries to run a query against a separate SQL Server machine using the authenticated user's own Windows identity, expecting the database to enforce per-user permissions. This consistently fails. Explain what's happening, using this chapter's own terminology.
📄 View solutionAn ipSecurity section sets allowUnlisted="false", allows the subnet 203.0.113.0/24, and separately denies the single address 203.0.113.50, which falls inside that subnet. Will a request from 203.0.113.50 be allowed or denied? Explain using the actual evaluation rule.
📄 View solutionChapter 8 Quick Reference
- Negotiate tries Kerberos first, silently falls back to NTLM — the fallback is invisible unless specifically checked for
- SPN gotcha: Kerberos needs a registered SPN for the exact hostname used; missing it fails Kerberos silently (masked by the NTLM fallback)
- Double-hop problem: a user's Windows identity doesn't forward to a second backend server by default — NTLM never supports it; Kerberos needs explicit delegation configuration
- Request Filtering — a native module rejecting oversized/malformed/forbidden requests before any handler or auth module runs (size limits, file extensions, hidden path segments)
- IP/Domain Restrictions —
allowUnlistedsets the default for unmatched IPs; specific entries win over broader ones regardless of listed order - Authentication is a security-sensitive section, typically
Deny-locked at the machine level (Chapter 3) — expect a<location>override or machine-level change, not a per-applicationweb.configedit