IIS 7 introduces many new security improvements from IIS 6.0. This document overviews these improvements with respect to Authentication, Authorization, SSL, Web Service Extension Restriction List and IP restrictions.
Authentication
For ASP.NET application developers there had been, before IIS 7, two authentication models you needed to program against. These models were the IIS and ASP.NET pipelines. First, IIS would examine the request and perform its authentication routines and then afterwards pass it to ASP.NET so it could do a similar task.
In IIS 7 we have unified these two models to produce a new robust pipeline that does the best that both older models did. IIS still supports all the old authentication protocols but also now supports forms authentication which can protect against all content types and does not rely on Windows accounts. In addition to supporting all the old features you have come to know and love we have also enhanced some of them such as the Anonymous Authentication feature.
These changes will be discussed in the upcoming sections.
Anonymous Authentication Changes
In IIS 7, Anonymous Authentication behaves in a similar manner as it had in previous versions with only one change - the ability to run under the content of the worker process identity. Each application pool is configured to run under the content of a user account and the default value for this account is NETWORKSERVICE.
It was very common for ASP.NET applications to turn off impersonation and run under the application pool identity by using the following code in their web.config files:
<identity impersonate="false"/>
There are several scenarios where applications would need to run under the context of the process identity:
- The process identity is a low privilege account and administrators have locked down their systems for that account
- The process identity has been granted network access and is used to access back end resources such as databases
As part of the IIS 7 redesign, we wanted to make this scenario secure and easy to do. To implement this scenario, in IIS 7 requires:
- Installing and enabling the Anonymous Authentication module
- Setting the anonymous username and password to an empty string
To do this, modify your configuration for anonymous authentication so it appears as follows:
<anonymousAuthentication enabled="true" userName="" defaultLogonDomain="" />
This configuration will tell IIS to run always under the context of the worker process identity.
By default, the anonymous authentication identity in IIS 7.0 is the IUSR account. This account is a low privilege identity with minimal rights and privileges. To learn more about the new built-in account refer to the
Understanding the Built-in Account and Group in IIS 7 article.
Passport Changes
Support for legacy Passport authentication was built into IIS 5/6 and Windows Server 2000 and 2003. Passport support in IIS 5 & 6 was exposed as a checkbox in the Directory Security tab in the IIS service manager for “Enable Passport Authentication”. This checkbox provided IIS the ability to send legacy Tweener protocol challenges. In addition to this, it was still necessary to register the Web site with the Passport service provisioning portal, obtain an encryption key, and configure the legacy Passport Manager on the server before the IIS integration would be functional.
In Windows Server 2008 and beyond, the legacy Passport binaries and integration with IIS were removed.
The Passport service has since changed into Windows Live ID. While the new Live ID service certainly grew out of the legacy Passport service, there are major changes. One of the biggest changes is how a partner site integrates with Live ID. You can add Live ID authentication by using the publicly available
Windows Live ID Web Authentication SDK. While the Windows Live ID service also supports identity Federation and ADFS, that capability is new functionality for specific cases, and is not a replacement for “Passport”.
Forms authentication
Forms authentication has been part of ASP.NET and allows both Windows and non Windows identities to authenticate themselves and get a user object that applications can later use. IIS 7 now fully supports forms authentication and can be configured to protect access to all content types.
How IIS 7 Determines the Authenticated Identity
In IIS 7 the authentication rules are processed by the core engine in a similar manner as they were in previous versions of IIS with only some minor changes. To better understand the processing order, here are the rules based on the order IIS evaluates them:
- First, IIS determines if a username and password has been configured at the virtual directory. If a set of credentials have been defined, those credentials will be used. For pre-IIS 7 administrators, these credentials are the UNC credentials
- If no credentials are configured at the virtual directory then IIS will use the credentials provided during authentication. These credentials can belong to the identity that is configured for anonymous authentication or the credentials provided by the user during the authentication handshake when Basic, Digest, or Windows authentication is enabled
- If no authenticated user was established (for example, forms authentication is enabled) we will determine if the process identity should be used
- If we do not have an identity at this point, IIS will return an access denied
Authorization
AzMan Support
In IIS 6.0, we introduced a new authorization model based on AZMan rules. In IIS 7 we have deprecated this feature in favor of a new model that is very similar to the ASP.NET authorization model (see URL authorization topic below).
URL Authorization
In IIS 7, you have two authorization solutions. The first is to use the ASP.NET authorization model. This method requires defining all your authorization rules in the <system.web> configuration and requires zero changes for applications that already have rules written for ASP.NET. The second model is to move to the new IIS 7 authorization architecture. This model is very similar to ASP.NET's model with some minor changes:
- Rules are not order dependent
- Deny rules are sorted to the top of the list
- Rules are processed in the opposite manner of ASP.NET, mainly in the order: grandparent, parent, then child; ASP.NET authorization processes rules in the opposite order:child, parent, then grandparent
To better understand the differences between ASP.NET and IIS 7 authorization models, let's first look at an ASP.NET authorization configuration:
<authorization>
<allow users="Vik_Malhotra" />
<deny roles="administrators" />
<deny users="*" />
</authorization>
In this example we are allowing Vik_Malhotra but we are denying everyone else. In IIS 7 the configuration is very similar:
<authorization>
<add accessType="allow" users="Vik_Malhotra" />
<add accessType="deny" roles="administrators" />
<add accessType="deny" users="*" />
</authorization>
The reason for the syntax change was that we wanted to make sure application developers knew these two models are in fact different, but at the same time they could move rules from one implementation to the other with minimal effort.
SSL
In IIS 6.0, IIS had stored SSL related information in the metabase and had managed a large part of the SSL negotiation process in conjunction with HTTP.SYS. In IIS 7, we have moved most of this configuration into HTTP.SYS's store.
Web Service Extension Restriction List
In IIS 7 this feature has been slightly modified so that its name now reads "isapiCgiRestrictionList" -- but otherwise it acts and behalves as it had in IIS 6.0.
The reason for this change was to stress its true usage. In IIS 6.0 this feature was added to ensure rogue ISAPI or CGI binaries could not copied to your IIS servers and then be allowed to execute. With the new IIS 7 redesign we have two supported models:
- The "classic" ISAPI pipeline
- The new Integrated pipeline
If we are in the "classic" ISAPI pipeline, everything will continue to work as you would expected it to when using IIS 6.0. To illustrate this point, consider how ASP.NET works when running in ISAPI mode. First you will need to add the full path of the aspnet_isapi.dll and set it allowed="true" as shown below:
<isapiCgiRestriction>
<add path="F:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll"
allowed="true" groupId="ASP.NET v2.0.50727" description="ASP.NET v2.0.50727"
</isapiCgiRestriction>
Now and only now will this code (aspnet_isapi.dll) be allowed to execute. If we switched our pipeline mode to integrated and changed allowed="false" the ASP.NET code will still be executed.
Why? The reason is the isapiCgiRestrictionList only applies to ISAPI and CGI code. In integrated mode, ASP.NET is now part of the new architecture and as a result is not affected by the isapiCgiRestrictionList. If you do not want to run ASP.NET code in the new integrated pipeline you will simply need to remove the managedEngine from the modules list.
IP Restrictions
IP Restrictions works in the exact same manner as it had in the past except we now support a new property called "allowUnlisted". This property was added to make it easier to configure security policies for your system at a global level. For example, if your policy required only certain IP addresses to be allowed but to reject all others that are not listed was not very easy to do in the past. Similarly, rejecting only a given set of IP addresses and allow ing all that are not listed can easily be done now. As a server administrator you can set a global policy and then lock this value so it cannot be changed on your server by application or site administrators.
To illustrate, consider a development machine you only want users to access locally. The following configuration implements that policy by setting the allowUnlisted="false" and then explicitly only allows localhost (127.0.0.1) access:
<system.webServer>
<security>
<ipSecurity allowUnlisted="false">
<add ipAddress="127.0.0.1" allowed="true" />
</ipSecurity>
</security>
</system.webServer>