Reputation: 12419
I was setting up permissions for pages in a ASP.NET website with <location>
tags in web.config, something similar to this:
<location path="Users.aspx">
<system.web>
<authorization>
<allow roles="Administrator"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
However, I also have a web.sitemap which basically contains the same information, i.e. which user roles can see/access which pages. A snippet from my web.sitemap:
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode title="Home">
... lots of nodes here ...
<siteMapNode url="users.aspx" roles="Administrator" title="users" description="Edit users" />
...
</siteMapNode>
</siteMap>
Is there some kind of nifty way of using web.sitemap only to configure access? The <location>
tags are quite verbose, and I don't like having to duplicate this information.
Upvotes: 1
Views: 8403
Reputation: 100248
Here is the code of my own SiteMapProvider
which throws an exception where user being requested a page (node) has no right to do that (his role isn't in the list of node's roles)
public class XmlSiteMapProvider : System.Web.XmlSiteMapProvider
{
public override bool IsAccessibleToUser(HttpContext context, SiteMapNode node)
{
var roles = node.Roles.OfType<string>();
if (roles.Contains("*") || (roles.Count(r => context.User.IsInRole(r)) > 0))
{
return true;
}
else
{
throw new InsufficientRightsException();
}
}
}
To implement my own roles logic I also made my own RoleProvider
.
Upvotes: 0
Reputation: 3107
Sure, you can define a SiteMapProvider in your web.config, and use the CurrentNode property to get the SiteMapNode related to the requested page.
First declare your siteMap provider (web.config) :
<siteMap enabled="true" defaultProvider="DefaultXmlSiteMapProvider">
<providers>
<add siteMapFile="Web.sitemap" name="DefaultXmlSiteMapProvider" securityTrimmingEnabled="true" type="System.Web.XmlSiteMapProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
</providers>
</siteMap>
Sample code for page access control with CurrentNode (you can do it better ;)) :
bool hasAccess = false;
if (SiteMap.CurrentNode == null)
throw new ApplicationException("Page not present in SiteMap : " + this.Request.Url.AbsolutePath);
if (SiteMap.CurrentNode.Roles.Count > 0)
{
// All roles or no roles
if (SiteMap.CurrentNode.Roles.Contains("*") == true)
{
hasAccess = true;
}
else
{
for (int index = 0; index < SiteMap.CurrentNode.Roles.Count; index++)
{
string role = SiteMap.CurrentNode.Roles[index].ToString();
hasAccess = HttpContext.Current.User.IsInRole(role);
if (hasAccess == true)
break;
}
}
}
Note I added the everyone role (*), very usefull.
Upvotes: 0
Reputation: 100248
Probably you're looking for SecurityTrimmingEnabled. See this forum post and blog entry for more details.
So Web.config
restricts access from direct URL typing and Web.sitemap
- from URLs being displayed
Upvotes: 1