The routing framework that was introduced with MVC has been available for use in WebForms since version 3.5, but doesn’t integrate well with some existing features, notably security trimming with site maps. This is where the site map provider will honour authorisation, only showing nodes for which the user is authorised. The trouble is, the url in the site map would be a route url, not the url of the physical file, so the security checking on the node doesn’t work. It doesn’t fail, just doesn’t work at all.
The solution is to customise the provider, which is easy enough since the code for all the providers is available at http://tinyurl.com/ASPNETProviders. Modifying the XmlSiteMapProvider, you can add the following:
public override bool IsAccessibleToUser(HttpContext context, SiteMapNode node) { if (!this.SecurityTrimmingEnabled) return true; SiteMapNode newNode = node.Clone(true); if (!string.IsNullOrEmpty(node["routeName"])) { Route r = (Route)RouteTable.Routes[node["routeName"]]; if (r != null) { newNode.Url = ((PageRouteHandler)(r.RouteHandler)).VirtualPath; ; } } return base.IsAccessibleToUser(context, newNode); }
This simple looks up the route name in the route table and gets the url of the physical file, passing that through to the base security checks. You also need to add the routeName attribute to your siteMapNode, so that an easy lookup can be done. You could iterate over the site map nodes finding the right one, but this is a slightly faster solution, although “faster” may not be that measurable.