ASP.net: Understanding sitemaps
One day Pete the web developer decided to build his friends a website using ASP.net.
He started out by creating a new web solution in his Visual Studio
(yes the one he pirated from one of his friends) and added a masterpage to his solution, next he decided to create folders defining all their diverse interests.
Pete felt that navigation is paramount, so he added a sitemap to the website and dropped a menu onto his masterpage where he bound the menu to his sitemap.
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode>
<siteMapNode url="~/Music/Default.aspx" title="Music" />
<siteMapNode url="~/History/Default.aspx" title="History" />
<siteMapNode title="Sport">
<siteMapNode url="~/Sport/Cricket/Default.aspx" title="Cricket"></siteMapNode>
<siteMapNode url="~/Sport/Rugby/Default.aspx" title="Rugby"></siteMapNode>
<siteMapNode url="~/Sport/Soccer/Default.aspx" title="Soccer"></siteMapNode>
</siteMapNode>
</siteMapNode>
</siteMap>
Pete called his friends over
(Jack & Paul) to have a look at his creation, immediately Jack noticed the Soccer menu item and cried out “Pete I am straight I don’t watch gay sports”
Soccer Officially Announces It Is Gay
Pete realised that he needed to add roles to his website
(Gay, Straight Roles), so he wacked a MembershipProvider & RoleProvider
(not discussed in this post) into his web.config and enabled security trimmings for his sitemap
<siteMap defaultProvider="XmlSiteMapProvider" enabled="true">
<providers>
<clear />
<add name="XmlSiteMapProvider"
type="System.Web.XmlSiteMapProvider"
siteMapFile="web.sitemap"
securityTrimmingEnabled="true" />
</providers>
</siteMap>
</system.web>
Next he altered his sitemap to include the needed roles, but for some reason it didnt work – can you spot the mistake he made?
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode roles="*">
<siteMapNode url="~/Music/Default.aspx" title="Music" />
<siteMapNode url="~/Fairies/Default.aspx" title="Fairies" roles="Gay" />
<siteMapNode title="Sport" roles="*">
<siteMapNode url="~/Sport/Cricket/Default.aspx" title="Cricket"></siteMapNode>
<siteMapNode url="~/Sport/Rugby/Default.aspx" title="Rugby"></siteMapNode>
<siteMapNode url="~/Sport/Soccer/Default.aspx" title="Soccer" roles="Gay"></siteMapNode>
</siteMapNode>
</siteMapNode>
</siteMap>
For some strange reason the “Gay” nodes were still showing, even though Jack logged in using his “Straight” role.
After googling himself on google for a few hours, Pete decided to actually use google for something useful and had a look all over
the web, to find out if other people are experiencing the same issue.
Pete eventually discovered the problem, one can’t define roles on a sitemapnode that include an url – it actually retrieves its visibility/accessibility from a location tag in the web.config.
(Which
makes sense from a security point of view – whats the use of hiding a page from a menu if we still have access to the
page regardless)
So Pete fixed his sitemap by removing all the invalid roles
(while wondering why Microsoft didn’t simply throw an exception
if someone made this mistake)
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode roles="*">
<siteMapNode url="~/Music/Default.aspx" title="Music" />
<siteMapNode url="~/Fairies/Default.aspx" title="Fairies" />
<siteMapNode title="Sport" roles="*">
<siteMapNode url="~/Sport/Cricket/Default.aspx" title="Cricket"></siteMapNode>
<siteMapNode url="~/Sport/Rugby/Default.aspx" title="Rugby"></siteMapNode>
<siteMapNode url="~/Sport/Soccer/Default.aspx" title="Soccer"></siteMapNode>
</siteMapNode>
</siteMapNode>
</siteMap>
And added the Gay locations to his web.config like this:
</system.web>
<location path="Sport/Soccer">
<system.web>
<authorization>
<allow roles="Gay" />
<deny users="*" />
</authorization>
</system.web>
</location>
<location path="Fairies">
<system.web>
<authorization>
<allow roles="Gay" />
<deny users="*" />
</authorization>
</system.web>
</location>
When Jack logs in, he now only sees the items he wants to see
Note:
If security isnt a concern, one can always alternative simply create a custom SiteMapProvider, where one can inforce the roles attribute on a sitemapnode containing an url .
using System;
using System.Linq;
using System.Web;
namespace CSTruter.Web
{
public class SiteMapProvider : XmlSiteMapProvider
{
public override bool IsAccessibleToUser(HttpContext context, SiteMapNode node)
{
if (node.Roles.Count == 0)
{
return base.IsAccessibleToUser(context, node);
}
else
{
return (from role in node.Roles.OfType<String>()
where context.User.IsInRole(role) || (role == "*")
select role).Count() > 0;
}
}
}
}
Posted by - Christoff Truter
Date - 2010-07-17 15:12:02
Comments
Post comment