Once a requesting client has been authenticated, the server must then determine whether this user is allowed to access the resources it is requesting. This process is known as authorization. You have already seen an example of authorization in Example 19-4 and Example 19-5, in the <authorization> sections in web.config. The details of authorization will now be explained. There are two ways of authorizing users: file authorization and URL authorization.
19.2.1 File Authorization
Any Windows operating system that supports NTFS (this includes Windows 2000, Windows XP, and Windows 2003) uses a security system based on Access Control Lists (ACLs). ACLs control access to any specific file or directory based on the requesting user's membership in a Windows Domain or Active Directory and the group(s) to which that user belongs. You have seen users and groups in Figure 19-3.
If all the legitimate users of a web application are known to have Windows user accounts, then you can use file authorization to authorize a user's access to a resource. Each user is assigned to an appropriate group and that group is given the necessary permissions, using the Computer Management console, to use the application.
You can examine the ACL for any file or directory in Windows by right-clicking on the object in Windows Explorer, selecting the Properties menu item, then going to the Security tab. You will see something similar to Figure 19-6.
In Figure 19-5, the single-headed icon represents a user and the two-headed icons represent groups. Each of the users and groups listed in the Name box can have a different set of permissions. These permissions available for each file or folder, shown in Figure 19-5, are easily set by checking and unchecking the checkboxes to allow or deny the permission.
When a request is received and authenticated by IIS, there is one of two possibilities: either it is authenticated as a known user, or it is treated as an anonymous user. If the request is from a known user, then, of course, the username is known. If the request comes from an anonymous user, then it is assigned to the standard user account IUSR_MachineName, where the name of the server machine is substituted for MachineName.
This is relevant because it is the username that ultimately determines which resources are available to a user. This depends on the impersonation mode currently set. (Impersonation will be described shortly.) If impersonation is enabled, the application will run with the permissions assigned to the user. If impersonation is not enabled, the application will run with the permissions of the ASP.NET account.
There are two liabilities to file authorization:
19.2.2 URL Authorization
URL authorization allows for both positive and negative authorizations. In other words, authorizations can be either allowed or denied. In addition, authorizations can be based on usernames, on roles, or on the HTTP verb.
Access conditions are contained within an <authorization> section in the web.config file. A simple example was shown in Example 19-4 and Example 19-5. As with all configuration files, the conditions apply to the current directory and all subdirectories unless overridden by web.config files contained in those subdirectories.
One or more access elements are contained within the <authorization> section. The permissible access elements are either <allow> or <deny>. Both access elements may be present in the same <authorization> section, in which case the first match found will take precedence.
Within each access element, there are one or more attributes. There are three possible attributes, listed in Table 19-2.
Either the Roles or Users attribute must be present. Both are allowed simultaneously, but both are not required. The Verbs attribute is optional.
Consider the following <authorization> section:
<authorization> <allow users="Dan, Jesse, stersol\Jennifer" roles="Administrators" /> <deny users="Bill" /> <deny users="?" /> </authorization>
This example will allow local domain users Dan and Jesse, as well as Jennifer, who is a member of the stersol domain. All members of the Administrators group will also be allowed access. Bill will be denied access, and all anonymous users will also be denied access.
Consider the next sample <authorization> section:
<authorization> <allow verb="GET" users="*" /> <allow verb="POST" users="Dan, Jesse" /> <deny verb="POST" users="*" /> </authorization>
In this example, all users will be allowed if the request is a GET request. Dan and Jesse are allowed to make POST requests, but all other users making post requests will be denied access. This type of scenario might be useful because GET requests are typically used for simple requests with few parameters, such as may be sent by a link on a web page, while POST requests are typically sent by forms, with much more robust access.
As with all configuration file settings, the system merges all the access rules from all the configuration files contained in the hierarchy of directories and subdirectories of the application. It then checks the rules for each request, starting at the head of the list and moving down the list until the first match is found. If a match is found and the access element is <deny>, then a 401 error will be returned.
The default <authorization> section contained in machine.config contains the following line, which allows all identities:
<allow users="*" />
Therefore, if there are no <authorization> sections in any of the web.config files, all users will be granted access to the application. Likewise, if no matches are found, the user will be granted access.
If you want a subdirectory of the application virtual root directory to have different access rules than its parent directory, you have two choices. One possibility is to include a web.config file in the desired subdirectory. However, any rules it contains will also apply to its subdirectories, and so on. This may cause logistical problems similar to ACLs.
An alternative way to apply different access rules to a specific subdirectory is to use the <location> tag in the web.config file. Consider the web.config file shown in Example 19-14.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.web> <authentication mode = "Forms"> <forms name="ProgAspNetCookie" loginUrl="vbLoginForm.aspx" > <credentials passwordFormat="Clear"> <user name="Tom" password="mot" /> <user name="Dick" password="kcid" /> <user name="Harry" password="yrrah" /> </credentials > </forms> </authentication> <authorization> <deny users="?" /> </authorization> </system.web> <location path="pages/public.aspx" > <system.web> <authorization> <allow users="*" /> </authorization> </system.web> </location> <location path="pages" > <system.web> <authorization> <allow users="Dan, Jesse " roles="Administrators" /> </authorization> </system.web> </location> </configuration>
The web.config file shown in Example 19-14 specifies that the application will use forms authentication. Tom, Dick, and Harry will be authenticated, and all other users will be denied access, except that the file called public.aspx contained in the pages subdirectory of the application root will allow all users to access it. In addition, Dan, Jesse, and all members of the Administrators group will have access to the pages subdirectory.