Examining ASP.NET 2.0's Site Navigation - Part 3By Scott Mitchell
In addition to this article series on ASP.NET 2.0's site navigation, I am also currently authoring an article series on ASP.NET 2.0's membership, roles, and profile. The membership system in ASP.NET provides a programmatic API for creating and managing user accounts, whereas the roles piece enables a developer to define a set of roles and to associate users with roles. A website that provides user accounts typically has certain sections of the site that are accessible only to certain users, only to authenticated users, or to users that belong to a particular role.
For example, a website might have a set of pages that allow a trusted user to edit the content of the website, or manage the existing users. Rather than simply trying to hide this page and hope no one accidentally stumbles across it, or hard coding authorization rights to only allow in a single user, a more robust and secure approach is to define an Administrator role that is then assigned to a select handful of trusted users. These administrative web pages can then be configured to allow access only to those users in the Administrator role. Similarly, the website may contain a set of pages that only authenticated users can access.
Since certain sections of the site might only be accessible by certain users this leaves us in a delimma with site navigation. Do we include those pages that only authorized users can access in the website's site map? If we do, then all users will see the restricted pages in the site's Menu or TreeView. Why show the links to these pages for users who can't access them? If we leave out the restricted pages from the site map altogether, then those users that are authorized to view those pages can't easily navigate to them because they're not part of the site map and therefore don't appear in the site's TreeView or Menu!
Thankfully, ASP.NET 2.0's site navigation provides a feature called security trimming. When obtaining site map information with security trimming enabled, only those site map nodes that the currently logged on user has authorization to visit are available. That means the site's TreeView or Menu will contain just those sections accessible by the currently logged in user. Read on to learn how to configure site navigation to support security trimming!
First Things First: Configuring ASP.NET 2.0's Membership and (Optionally) Roles
Since the site navigation security trimmings bases the site map data on the user visiting the page and the authorization settings defined for the pages in the site map, before we can examine security trimming you must first configure your website to use ASP.NET 2.0's Membership services. (You can also configure the site to use roles, and take advantage of role-based authorization, but this is not required to exhibit the security trimmings concept.) A discussion on how to configure a site to use Membership and Roles is beyond the scope of this article; refer to the Examining ASP.NET 2.0's Membership, Roles, and Profile article series for more information (Part 1 for setting up Membership, Part 2 for setting up Roles).
The download at the end of this article includes a working example of a security trimming site map for a website that implements Membership and Roles, which you can use if you don't want to take the time to setup the Membership and Roles feature on a fresh website. Specifically, the downloadable website at the end of this article contains two roles, Administrator and Tester, with four users:
- Superman, in the Administrator and Tester roles
- Admin, in the Administrator role
- Mr. Tester, in the Tester role
- Average User, not in any roles
AuthUsersOnly. The first two folders have been configured to only allow users in the Administrator and Tester roles, respectively. The
AuthUsersOnlyfolder is restricted to allow only authenticated users.
Configuring Site Navigation to Use Security Trimmings
By default, site navigation does not use security trimming. Regardless of what user is visiting the site, and regardless of the authorization rules defined, each user is shown all of the sections in the site map when viewing the site map data through a TreeView or Menu Web control. By turning on security trimmings, the site navigation system automatically limits the results based on the currently logged on user and the authorization of the pages referenced by the
<siteMapNode>elements in the site map.
The site navigation settings can be configured through the
Web.config file using the following pattern:
Recall from our discussions in Part 1 of this article
series that the site navigation system uses the provider model.
This model offers developers a well-defined, public API, but allows the inner workings to be customized, if needed. By default,
the site navigation feature uses the
XmlSiteMapProvider, which obtains site map information from the XML-formatted
site map file
Web.sitemap. You can change what provider is used, or tweak the default provider's default settings,
To customize the default provider's settings, simply add a new provider that uses the same type as the default provider
System.Web.XmlSiteMapProvider), customizing the settings as needed.
The snippet of markup shown above illustrates customizing two of the
siteMapFilesetting specifies the filename of the site map file used by the provider; by default, this value is
Web.sitemap. You can customize the filename here, if you like. Regardless, I'd encourage you to ensure that the site map filename ends with the
.sitemapextension, since this extension is protected by the ASP.NET engine by default, thereby preventing web visitors from viewing the site map file.
securityTrimmingEnabledsetting indicates whether or not security trimming is used. To utilize security trimming, set this to true, as shown above.
<siteMapNode>elements. The following screenshots show the TreeView displayed when visited by an anonymous visitor (one who has yet to login), an Average User, and the Admin user. The anonymous visitor sees just two links, Home and My Blog. Average User sees an additional link, Auth Users, which the anonymous visitor did not see because this node's URL (
~/AuthUsers/Default.aspx) is configured to only allow authenticated users. The Admin user sees an additional link because he is the Administrator role and the URL pointed to by the Admin site map node (
~/Admin/Default.aspx) is configured to only allow access to Administrators.
|The TreeView When Visited by an Anonymous Visitor|
|The TreeView When Visited by Average User||The TreeView When Visited by Admin|
Preventing Security Trimmings with the
There may be times when you want to explicitly inform the security trimming to not trim a site map section for a particular role or set of roles. For example, if your site map contains a link to an external resource, the site navigation system cannot determine the authorization rules for this remote resource. Therefore, it trims the node for all users. That is, if you have security trimming enabled and are using a site map with an external link (like
<siteMapNode url="http://www.scottonwriting.net/sowBlog/" title="My Blog" />), no users will see this in the TreeView or Menu controls. Rather, you might want to instruct the site navigation system to show this node for those in the Administrator and Tester roles, nevertheless. (Or, alternatively, for all users, regardless of their role.)
Similarly, you may want to show a local site map node to users, even if they don't have authorization to access that resource.
For example, a user who visits the site and has yet to login clearly won't see the
Admin link in the TreeView.
However, we might want to still show this. Clicking it would cause the user to be taken to the
page, where the system would see that they're not authenticated. This would direct them to the login page. After logging in,
they'd be auto-redirected back to the Admin page. If they were not in the Administrator role, they'd be sent back to the
login page, otherwise they'd be granted access to the Admin section.
To not trim particular roles for a particular site map node, use the
roles attribute in the corresponding
<siteMapNode> elements. (Note: this setting does not apply to descendent
that is, you must explicitly set this attribute on each
<siteMapNode> element for which you want to explicitly
specify additional roles that should see the node.) The
roles attribute can contain one role name, a comma-delimited
list of role names, or an asterisk (
*) to denote all users. The following site map file, included in the download
at the end of this article, shows how to use the
roles attribute to have an external site map node reference
appear for all users. (Realize that omitting the
roles attribute here would have the effect of not showing
this site map node to any users when security trimming is enabled...)
roles attribute can also be used to add a slight performance boost to the security trimmings functionality.
With security trimmings enabled, the site navigation provider automatically checks the authorization rules for all nodes defined
in the site map. You can bypass this check for those nodes you want to show to all users (such as Home and About, in the above example)
roles="*". By adding this attribute you will shortcut the normal authorization check, thereby improving
the security trimming performance.
In addition to providing site navigation support, ASP.NET 2.0 makes it easy to build websites that include user account support and role-based authorization. It comes as no surprise, then, that these two systems can interoperate and provide a site map whose returned contents are based upon the currently logged on user and the authorization settings of the URLs defined in the site map. Configuring the site navigation to limit the results based on the visiting user and the authorization settings is as easy as adding a couple of lines to the