4.11. Use Role-Based Authorization
In many web applications, all users are not equal. Some might be allowed to perform a carefully restricted set of actions, while others are given free reign to perform more advanced administrative tasks. ASP.NET 2.0 makes it easier than ASP.NET 1.x to assign permissions to different groups of users using the new role-management service.
Note: Do you need to give different privileges to different types of users? The easiest way to implement this logic is by using ASP. NET's new role-management service.
4.11.1. How do I do that?
ASP.NET uses a role-management service to manage the storage and retrieval of role-based information. ASP.NET gives you the flexibility to use different role-manager providers to store the role information in different data sources. Usually, you'll use the same data store that you use for membership (as described in the lab "Easily Authenticate Users"). Because the membership provider and the role-manager provider use different tables, you don't need to worry about a conflict.
Role management is not enabled by default. You can enable it by using the WAT, as described in the lab "Administer a Web Application." Just select Website ASP.NET Configuration and choose the Security tab. Then click the "Enable roles" link in the Roles box. This modifies the web.config as needed. However, you'll still need to configure the roles you want to use.
The easiest way to add role information is also through the WAT. To do so, click the "Create or Manage roles" link in the Roles box on the Security page. This presents a page where you can add new roles and assign users to existing roles. To add a new role, type in the role name and click Add Role. You'll see the role appear in the list below. Figure 4-14 shows an example with two groups, Administrators and Sales Officials. Note that you won't see group membership on this page.
Figure 4-14. Adding a new role
To change group membership, click the Manage link next to the appropriate role. Because a typical system could easily have hundreds of users, the WAT does not attempt to show all the users at once. Instead, it allows you to specify the user that you want to add to the role by typing in the name, browsing an alphabetical directory, or using a search with wild cards (as in John* to find usernames starting with John). Once you've found the appropriate user, place a checkmark in "User Is In Role" column to add the user to the role, or clear the checkbox to remove the user, as shown in Figure 4-15.
Figure 4-15. Assigning a role to a user
Using this tab, you can examine the list of users (including the test user you added in the previous step) and modify their information. What you really need to do, however, is click the "Create access rules" link to restrict access to the Secured directory. Select the directory in the list, choose the Deny Permission option, and select Anonymous users, as shown in Figure 4-13. Then, click OK to add this rule.
When a user logs in using forms authentication (as described in the lab "Easily Authenticate Users"), the role-management service automatically retrieves the list of roles that the user belongs to and stores them in an encrypted cookie. After this point, it's easy to test the role membership of the currently logged-in user.
For example, the following code checks if the user is an Administrator. In order for this to work, the user must have logged in:
If Roles.IsUserInRole("Administrator") Then ' (Allow the code to continue, or show some content ' that would otherwise be hidden or disabled.) End If
And, finally, this code displays a list of all the roles that the user belongs to:
For Each Role As String In Roles.GetRolesForUser( ) lblRoles.Text &= Role & " " Next
Clearly, none of these tasks requires much work!
You can also set and retrieve role information using the System.Web.Security.Roles class. Here are the core methods you'll want to use:
The following code snippet creates a role and adds a user to that role:
Roles.CreateRole("Administrator") Roles.AddUserToRole("testUser", "Administrator")
4.11.2. What about...
...performance? At first glance, role management might not seem very scalable. Reading the role information for each web request is sure to slow down the speed of your application, and it may even introduce a new bottleneck as ASP.NET threads wait to get access to the database. Fortunately, the role-management service is quite intelligent. It won't make a trip to the database with each web request; instead, it retrieves role information once, encrypts it, and stores it in a cookie. For all subsequent requests, ASP.NET reads the roles from the encrypted cookie. You can remove this cookie at any time by calling Roles.DeleteCookie(), or you can configure settings in the web.config file to determine when it should expire on its own.
If you have an extremely large number of roles, the cookie might not contain them all. In this case, ASP.NET flags the cookie to indicate this fact. When your code performs a role check, ASP.NET will try to match one of the roles in the cookie first, and if it can't find a match, it will double-check the data source next.
4.11.3. Where can I learn more?
For more information, look up the index entry "role-based security ASP.NET in the MSDN Help.