ASP.NET 4 Unleashed
When should you use Windows authentication instead of other forms of authentication such as Forms or Microsoft Passport authentication? If you are developing a company intranet, you can use Windows authentication with existing Windows user accounts and groups. For example, your organization might already have Windows user accounts configured for each employee. You can use Windows-based authentication to control access to sensitive information. For example, you might want users in the Windows Managers group to have access to directories containing employee resumes and job performance reviews. You can use Windows-based authentication to prevent employees in other Windows groups, such as the Sales group, from accessing these sensitive documents. Windows-based authentication is not a good security option to use, however, when you're building a public user registration and password system. When Windows authentication is enabled, a valid Windows user account must be configured for each user who accesses a restricted page. The process of adding new Windows user accounts cannot be easily automated. You therefore should use Windows authentication when you have a fixed number of users with existing Windows user accounts and an existing system of group membership. Don't use Windows authentication when you're building a public user registration systemuse Forms authentication instead. Configuring Internet Information Server Security
Before you can use Windows authentication, you must first configure Internet Information Server (IIS). When a user requests a page that requires authorization, the user must be authenticated through IIS. The version of IIS included with Windows 2000 Server, IIS 5.0, supports three methods of authentication:
Typically, you enable either Basic Authentication or Integrated Windows Authentication. If your application must be compatible with Netscape browsers, you have no choice but to use Basic Authentication. If you can mandate that all users must use Microsoft Internet Explorer and you are not using a firewall or proxy server, you can use Integrated Windows Authentication.
NOTE You can use the Secure Sockets Layer (SSL) with Basic Authentication to encrypt usernames and passwords as they are transmitted across the network. For more information, see Chapter 21 "Encrypting Data over the Network."
To enable one of these authentication methods for a directory or file, follow these steps:
After you enable a method of authentication, you can force users to log in to your Web site through IIS in two ways. First, you can disable anonymous access to a file or directory. Follow the same steps just described for enabling authentication and click to remove the check from the Anonymous Access option. Alternatively, you can modify the NTFS permissions on a file or directory. If an anonymous user does not have permission to access a file, the password dialog box is displayed even when anonymous access is enabled. You learn how to configure Windows file permissions in the next section. Configuring Microsoft Windows Security
Windows NT and Windows 2000 implement security at the file system level. Every directory and file has an associated set of permissions. These permissions are defined relative to Windows users and groups.
CAUTION To set permissions on individual files, you must be using NTFS. Using NTFS is strongly recommended if you plan to use Windows authentication.
Windows 2000 includes several default users and groups. For example, the Administrator user account has the broadest set of possible permissions. The Administrator account is a member of the Administrators group. When configuring Windows authentication with ASP.NET, you'll need to work with the following users and groups:
At a minimum, in order to enable anonymous access to the files in a directory, you'll need to grant Read & Execute permissions to two user accounts: the ASPNET and IUSER_ MachineName user accounts. The ASPNET user account represents the ASP.NET worker process and the IUSER_ MachineName account represents an anonymous Internet Information Server user.
NOTE You can use IIS to change the account associated with anonymous users from the IUSER_ MachineName account to any other account. You can modify the anonymous user account within IIS by opening the property sheet for a directory, selecting the Directory Security tab, and clicking the Edit button under Anonymous Access and Authentication Control.
Since both the ASPNET and IUSER_ MachineName user accounts are part of the Users group, the Authenticated Users group, and the Everyone group, you also can enable anonymous access for a directory by simply granting Read & Execute permissions to one of these groups. For example, you can enable anonymous access by granting Read & Execute permissions on a directory to the Users group.
NOTE There is a special problem that you encounter when executing ASP.NET on a primary or backup domain controller. Since a primary or backup domain controller cannot include non-administrative local accounts, on these machines the ASP.NET worker process must be configured to execute under the local system account. See the later section in this chapter, "Executing ASP.NET Pages under a User Account," for more information.
If you want to prevent anonymous access to a directory, then you can simply remove the IUSER_ MachineName user account from that directory. For example, imagine that you want to enable only the Administrator account to access the files in a directory. Follow these steps:
After you complete these steps, if you request any file in that directory with your Web browser, a Login dialog box is displayed. You are forced to log in with a user account that has access to the directory (in this case, the Administrator user account). You can provide any user or group with permissions to access any directory or file in your Web site. Simply add the user or group by using the Security tab associated with the file or directory. Configuring Windows Authentication
Windows authentication is enabled by default in the Machine.Config file. This setting is automatically inherited by all ASP.NET applications running on the same server. If you have modified the Machine.Config filefor example, you've set the default authentication method to Forms authenticationyou can explicitly enable Windows authentication for an application by adding the Web.Config file in Listing 20.1 to the application root directory. Listing 20.1 EnableWindows\Web.Config
<configuration> <system.web> <authentication mode="Windows" /> </system.web> </configuration> The C# version of this code can be found on the CD-ROM. You cannot add the file in Listing 20.1 to any directory beneath an application's root directory. In other words, it must be located in either the wwwroot directory or the root directory of a virtual directory. Configuring Windows Authorization
After enabling Windows authentication, you can provide authorization to particular users and groups to access particular directories and files. Again, you do so by using the Web.Config file. You can add a Web.Config file that includes an authorization section to any directory (not only the application root directory). Within the authorization section, you can list the users and groups who have access to files in that directory. The authorization section can contain two elements: deny and allow . You can use these elements to allow or deny a list of Windows users or groups access to the files in the current directory. For example, the Web.Config file in Listing 20.2 explicitly allows access to anyone in the Sales group, except for Jane. Listing 20.2 NoJane\Web.Config
<configuration> <system.web> <authorization> <allow roles="YourDomain\Sales" /> <deny users="YourDomain\Jane" /> <deny users="*" /> </authorization> </system.web> </configuration> The C# version of this code can be found on the CD-ROM. The authorization section uses a "first match" algorithm to allow or deny users and groups access to a page. Since the Sales role is allowed access before everyone is denied access, anyone in the Sales role is given authorization to access any page in the directory. Notice that the domain must be specified when listing user accounts and groups. If the user account or group is a local machine account, the domain is the name of your server.
NOTE When using Basic Authentication, you don't need to enter the domain when entering your username as long as it is the default domain for your application. You can specify the default domain associated with an application with IIS. Set this option within the Authentication Methods dialog box.
You can use two special wildcard characters in the authorization section of the Web.Config file. The * wildcard character represents all users, and the ? wildcard character represents all unauthenticated users. For example, if you want to force all users to log in before accessing a file in a directory, you can use the Web.Config file in Listing 20.3. Listing 20.3 NoAnon\Web.Config
<configuration> <system.web> <authorization> <deny users="?" /> </authorization> </system.web> </configuration> The C# version of this code can be found on the CD-ROM. Now you're ready to tackle a more complicated example. Say that you need to create two directories named Managers and Sales. You want to enable only users in the Managers group to access the files in the Managers directory. However, you want to enable members of both the Managers and Sales groups to access all the files in the Sales directory.
NOTE The files discussed in this section are located in the SimpleAuth directory on the CD that accompanies this book.
Imagine that you have two user accounts, one named Jane and one named George. The Jane user account is a member of the Managers group, and the George user account is a member of the Sales group.
NOTE As long as the Everyone group has access to the files in a Web application, you do not need to explicitly add either the Jane or George user accounts to the file permissions for the application.
By default, both Jane and George have access to every page in the application. To prevent George from accessing any file in the Managers folder, you need to add the Web.Config file in Listing 20.4 to the Managers folder. Listing 20.4 Managers\Web.Config
<configuration> <system.web> <authorization> <allow users="YourDomain\Jane" /> <deny users="*" /> </authorization> </system.web> </configuration> The C# version of this code can be found on the CD-ROM. The Web.Config file in Listing 20.4 explicitly allows Jane to access files in the current directory and explicitly denies everyone else access. Because George is not granted permissions to access files in the directory, he cannot access any files. To enable both Jane and George access to all files in the Sales directory, you can use the Web.Config file in Listing 20.5. Listing 20.5 Sales\Web.Config
<configuration> <system.web> <authorization> <allow users="YourDomain\Jane, YourDomain\George" /> <deny users="*" /> </authorization> </system.web> </configuration> The C# version of this code can be found on the CD-ROM. The Web.Config file in Listing 20.5 explicitly provides both Jane and George access to the files in the current directory. Configuring Custom Roles
Instead of using Windows groups for your roles, you can associate user accounts with custom roles. By using custom roles, you can invent any roles you want. To create custom user roles, you need to add a WindowsAuthentication_Authenticate subroutine in the Global.asax file. This subroutine is triggered whenever a user is authenticated using Windows authentication.
NOTE All the files in this section are located in the CustomRoles directory on the CD that accompanies this book.
The Global.asax file in Listing 20.6 uses the WindowsAuthentication_Authenticate subroutine to associate custom roles with authenticated users. Listing 20.6 CustomRoles\Global.asax
<%@ Import Namespace="System.Security.Principal" %> <Script Runat="Server"> Dim colRoles As HashTable Overrides Sub Init() colRoles = New HashTable() Dim arrJaneRoles As String() = _ { "Supervisors", "Engineers" } colRoles( "yourdomain\jane" ) = arrJaneRoles Dim arrGeorgeRoles As String() = _ { "Engineers" } colRoles( "yourdomain\george" ) = arrGeorgeRoles End Sub Sub WindowsAuthentication_Authenticate( _ s As Object, _ e As WindowsAuthenticationEventArgs ) e.User = New GenericPrincipal( _ e.Identity, _ colRoles( e.Identity.Name.ToLower() ) ) End Sub </Script> The C# version of this code can be found on the CD-ROM. In the Init() subroutine in the Global.asax file in Listing 20.6, custom roles are associated with the Jane and George user accounts. Jane is assigned to the custom roles Supervisors and Engineers. George is assigned to the custom role Engineers. The WindowsAuthentication_Authenticate subroutine is triggered whenever a user is authenticated with Windows authentication. Within this subroutine, a new instance of the GenericPrincipal class is created. This class associates the authenticated user account with the custom roles defined in the Init() subroutine. After you place the Global.asax file in Listing 20.6 in your application's root directory, you can refer to the custom roles in any Web.Config files contained in the application. When Jane is authenticated, she automatically becomes a member of the custom Supervisors and Engineers roles. When George is authenticated, he automatically becomes a member of the Engineers role. Now, imagine that you have a directory named Supervisors that contains information that should be viewed only by members of the custom Supervisors role. You can restrict access to the files in this directory by using the Web.Config file in Listing 20.7. Listing 20.7 CustomRoles\Supervisors\Web.Config
<configuration> <system.web> <authorization> <allow roles="Supervisors" /> <deny users="*" /> </authorization> </system.web> </configuration> The C# version of this code can be found on the CD-ROM. The Web.Config file in Listing 20.7 denies access to everyone except users in the Supervisors role. You can use custom roles to develop very complex role-based security systems. For example, you can store the custom roles in a database table and retrieve the table in the Global.asax Init() subroutine. Retrieving User Information
You can use two classes to retrieve information on users who have been authenticated by using Windows authentication: WindowsPrincipal and WindowsIdentity . You can use the WindowsPrincipal class to detect the roles to which an authenticated user belongs. For example, to check whether the current user is part of the Sales role, you can use the following statements:
If User.IsInRole( "Sales" ) Then Response.Write( "Welcome Sales Person!" ) Else Response.Write( "Go away!" ) End If The IsInRole method works both with roles that correspond to Windows groups and custom roles that you have created. You can use the IsInRole method to display different content to users depending on their role. For example, you might want to enable members of the Supervisors role to delete items in a database table, but not members of the Editors role. You also can retrieve information on authenticated Windows users by using the WindowsIdentity class, which has the following properties:
To display the user account associated with the current user, for example, you would use the following statement:
Response.Write( User.Identity.Name ) This statement displays the full user account name including the domain. To retrieve the other properties, such as IsAnonymous or IsGuest , you need to use the CType function to explicitly cast the user's Identity as a WindowsIdentity like this:
Response.Write( CType( User.Identity, _ System.Security.Principal.WindowsIdentity ).IsAnonymous ) This statement displays the value True before the user logs in, and False afterward. |