XmlSiteMapProvider only parse the first node - asp.net

I have an annoying problem and i can't find any start of a solution, so i hope you can help me.
I have a sitemap with roles defined for each node :
<?xml version="1.0" encoding="utf-8"?>
<siteMap enableLocalization="true">
<siteMapNode title="" url="" roles="">
<siteMapNode title="default" url="~/Default.aspx" roles="user" />
<siteMapNode title="supervision" url="~/EcranSupervision.aspx" roles="Admin" />
<siteMapNode title="exploitation" url="~/ChaineTraitementList.aspx" roles="Admin" />
</siteMapNode>
</siteMap>
And in my web.config, i enable security and i use a custom provider :
<siteMap defaultProvider="MainMenuSitemap">
<providers>
<add name="MainMenuSitemap" type="UbiXmlSiteMapProvider" siteMapFile="Web.sitemap" securityTrimmingEnabled="true" />
</providers>
</siteMap>
In my provider, i only override IsAccessibleToUser to do my logic :
public class UbiXmlSiteMapProvider : XmlSiteMapProvider
{
public override bool IsAccessibleToUser(HttpContext context, SiteMapNode node)
{
// custom logic here
}
}
My problem is that the node used in IsAccessibleToUser is always the one with the url "Default.aspx".
So if I have the role to see it, all the nodes are shown and if i don't have the role, none of the nodes are shown.
I don't understand what is wrong here.
Do you have a hint for me ?

Related

roles based menu does not work, what am I doing wrong?

I can't figure this one out.
I have the following SiteMap
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="~/" title="Root" description="Go root">
<siteMapNode url="~/h" title="Home" description="Go home" />
<siteMapNode url="~/h/uo" title="Ultima Online" description="Ultima Online">
<siteMapNode url="~/h/uo/get" roles="RegisteredUser" title="Get account!" description="Get account!" />
</siteMapNode>
</siteMapNode>
</siteMap>
I've an XmlSiteMapProvider with securityTrimmingEnabled="true", which points to this site map file.
The file I want to trim has an authorization rule in it's folder's web.config
<configuration>
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</configuration>
The file can't be accessed via url, if I type http://localhost/h/uo/get I get redirected to login page.
I've set up an <asp:Menu> like this in the Master page file:
<asp:SiteMapDataSource ID="MenuSiteMap" ShowStartingNode="false"
SiteMapProvider="MenuSiteMapProvider" runat="server"
/>
<div>
<asp:Menu ID="NavigationMenu" runat="server" DataSourceID="MenuSiteMap"
CssClass="menu" EnableViewState="false"
IncludeStyleBlock="false" Orientation="Horizontal"
/>
</div>
Yet, when the page is rendered, I see the Get account node that is supposed to be trimmed when I'm not even logged in, no matter what.
What am I doing wrong?
Is there any other way to build a security trimming enabled site map navigation menu?
I'm using ASP.NET 4.0, and URL-rewritting with an HttpModule.
In reading http://forums.asp.net/t/975077.aspx/1 I found out that this is exactly what is happening to me.
If the node doesn't have an URL it behaves fine, but if it does, like all of my nodes do. Security trimming is just ignored.
I resolved my problem by resorting to a more intuitive role based site map implementation, to say:
public class TrimmingXmlSiteMapProvider : XmlSiteMapProvider
{
public override bool IsAccessibleToUser(HttpContext context, SiteMapNode node)
{
if (node.Roles.Cast<string>().Any(r => r == "*"))
return true;
if (node.Roles.Count > 0 && node.Roles.Cast<string>().Count(Roles.IsUserInRole) == 0)
return false;
return node.ParentNode != null && node.ParentNode.IsAccessibleToUser(context);
}
}
Then, the only change I had to make was add an asterisk to the root level's role definition.
How does this work?
First I check if any of the roles definied for this node is an asterisk, if that's the case, then I can see the node.
Second, if the node isn't everyone-level, I check if there are any roles specified, and if the logged in user is part of at least one of them.
Lastly, I check if there is a parent node, and just inherit their rule.
This allows the security trimming to actually be "SECURITY TRIMMING" and not well, however the heck it's supposed to be working by default.

Breadcrumbs SiteMapPath and SEO-Friendly Routing

I have routing set up as follows:
void RegisterRoutes(RouteCollection routes)
{
routes.MapPageRoute("", "Home", "~/Default.aspx");
......
}
I'm implementing breadcrumbs using a SiteMapPath control:
<asp:SiteMapPath ID="SiteMapPath1" CssClass="breadCrumbs" runat="server">
</asp:SiteMapPath>
Web.sitemap is set up as follows:
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="Home" title="Home" description="Home">
<siteMapNode url="~/About" title="About" description="About">
<siteMapNode url="~/History" title="History"
description="History" />
</siteMapNode>
</siteMapNode>
</siteMap>
My problem is that when I navigate to mysite.com instead of mysite.com/default.aspx, the Home breadcrumb node does not appear. What am I missing?
UPDATE
I managed to get the "Home" node to display by updating Web.sitemap as follows:
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="Home" title="Home" description="Home">
<siteMapNode url="~/Default.aspx" title="" description="" />
<siteMapNode url="~/About" title="About" description="About">
<siteMapNode url="~/History" title="History"
description="History" />
</siteMapNode>
</siteMapNode>
</siteMap>
The only remaining problem is that the path separator is still displaying on home page for mysite.com
Is there a way to programatically render the separator invisible for the home page? The SiteMapPath control itself is in a master page.
Maybe you should change your sitemap file as follows :
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="~/" title="Global Site Name or Welcome Message" description="Home">
<siteMapNode url="~/Home" title="Home" description="" />
<siteMapNode url="~/About" title="About" description="About">
<siteMapNode url="~/History" title="History"
description="History" />
</siteMapNode>
</siteMapNode>
</siteMap>
and from the sitemapdatasource you should set ShowStartingNode="false" and I think that this solves both of your problems at once...
NOTE: of course this will require that you made this change in the global.asax file (VB):
RouteTable.Routes.MapPageRoute("Home0", "", "~/Default.aspx", True)
RouteTable.Routes.MapPageRoute("Home1", "Home", "~/Default.aspx", True)
hope this helps...

SiteMap based on user roles doesn't work

I have sitemap which looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="~/default.aspx" title="Prva stran" roles="*" description="Shema ISEF">
<siteMapNode roles="2" title="Analize" id="Analize" description="" >
<siteMapNode url="~/karneki1.aspx" title="Karneki1" description="" />
<siteMapNode url="~/karneki2.aspx" title="Karneki2" description="" />
</siteMapNode>
</siteMapNode>
</siteMap>
if I set roles in a siteMapNode with title "Analiza" it works fine, the link is not shown in the navigation... but if I set roles on any of "karneki" siteMapNode the links are still visible...
Is it even posible to restrict access to lower links based on user role?
Use the SiteMap 'securityTrimmingEnabled' attribute:
http://msdn.microsoft.com/en-us/library/ms178428.aspx
The asecurityTrimmingEnabled attribute also needs to be added to the nodes in the markup:
http://weblogs.asp.net/jgalloway/archive/2008/01/26/asp-net-menu-and-sitemap-security-trimming-plus-a-trick-for-when-your-menu-and-security-don-t-match-up.aspx
An overview of how securityTrimmingEnabled is supposed to work:
http://blogs.msdn.com/b/dannychen/archive/2006/03/16/553005.aspx
The solution to this is that you need to set the roles in a Web.config for the pages itself.
See http://weblogs.asp.net/jgalloway/archive/2008/01/26/asp-net-menu-and-sitemap-security-trimming-plus-a-trick-for-when-your-menu-and-security-don-t-match-up.aspx
e.g. in the folder for a page called AdminOnly.aspx add a Web.Config with the following:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="AdminOnly.aspx">
<system.web>
<authorization>
<allow roles="Administrator"/>
<deny users="*" />
</authorization>
</system.web>
</location>
</configuration>
Try to add the roles to the site map like this
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="~/default.aspx" roles="*" title="Prva stran" roles="*" description="Shema ISEF">
<siteMapNode roles="2" title="Analize" id="Analize" description="" >
<siteMapNode roles="*" url="~/karneki1.aspx" title="Karneki1" description="" />
<siteMapNode roles="*" url="~/karneki2.aspx" title="Karneki2" description="" />
</siteMapNode>
</siteMapNode>
</siteMap>

ASP.NET security trimming problem no fine grained control possible?

I have this sitemap:
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0">
<siteMapNode>
<siteMapNode url="www.google.com" title="Google" roles="*" />
<siteMapNode url="www.zdnet.com" title="Zdnet" roles="NonExistingRole" />
<siteMapNode url="www.microsoft.com" title="Microsoft" roles="*" />
<siteMapNode url="www.bing.com" title="Bing" roles="*" />
</siteMapNode>
</siteMap>
I am using a custom roleprovider configured like this (this works whenever I call for example the GetRolesForUser method):
<authentication mode="Windows"/>
<roleManager enabled="true" defaultProvider="MyProvider">
<providers>
<clear/>
<add name="MyProvider" type="CustomProviders.MyTestRoleProvider, CustomProviders, Version=1.0.0.0, Culture=neutral"/>
</providers>
</roleManager>
<siteMap defaultProvider="XmlSiteMapProvider" enabled="true">
<providers>
<clear/>
<add name="XmlSiteMapProvider" type="System.Web.XmlSiteMapProvider" siteMapFile="Web.sitemap" securityTrimmingEnabled="true"/>
</providers>
</siteMap>
What I expect is that the node with roles="NonExistingRoles" would not get visualized but it does. How to solve this problem?
Also do I need to turn on ?
Apparently it's because the root siteMapNode also needs a roles attribute set to * like this:
<siteMapNode roles="*">

I can't use Sitemap when I use UrlMapping

when I create folder for every page and remap those in web.config , appeared this problem .
1)I can't see content of pages.
2)When I use navigation controls , my web.SiteMap don't work and don't show path of pages.
what is problem in my project , and what I solve that ?
this link is my web site :
Urlmapping code :
<urlMappings>
<add url ="~/HOME" mappedUrl ="~/Default.aspx"/>
<add url ="~/a" mappedUrl ="~/a.aspx" />
<add url ="~/a1" mappedUrl ="~/a1/a1.aspx"/>
<add url ="~/a2" mappedUrl ="~/a2/a2.aspx"/>
<add url ="~/b" mappedUrl ="~/b/b.aspx"/>
<add url ="~/b1" mappedUrl ="~/b1/b1.aspx"/>
<add url ="~/b2" mappedUrl ="~/b2/b2.aspx"/>
<add url ="~/b3" mappedUrl ="~/b3/b3.aspx"/>
<add url ="~/c" mappedUrl ="~/c/c.aspx"/>
<add url ="~/c1" mappedUrl ="~/c1/c1.aspx"/>
</urlMappings>
SiteMap code :
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="~/HOME" title="Home" description="Home Page">
<siteMapNode url="~/a" title="page a" description="page a">
<siteMapNode url="~/a1" title="page a-1" description="page 1 of a" />
<siteMapNode url="~/a2" title="page a-2" description="page 2 of a"/>
</siteMapNode>
<siteMapNode url="~/b" title="page b" description="page b">
<siteMapNode url="~/b1" title="page b-1" description="page 1 of b" imageTitle="lake"/>
<siteMapNode url="~/b2" title="page b-2" description="page 2 of b" imageTitle="wolf"/>
<siteMapNode url="~/b3" title="page b-3" description="page 3 of b" imageTitle="thunder"/>
</siteMapNode>
<siteMapNode url="~/c" title="page c" description="page c">
<siteMapNode url="~/c1" title="page c-1" description="page 1 of c"/>
</siteMapNode>
</siteMapNode>
The problem is that the Url your are wanting is a actual folder in your wbesite so IIS picks this up first. There are acouple of ways to get around this.
Change all the .aspx filenames to be Default.aspx and these will be picked when you type http://website/a for example if you have a folder called "a" with Default.aspx in it, remove all the entries in the urlMappings
Have the URL as a different name to a actual directory
Use ASP.Net URL Routing that has been introduced in 3.5 SP1 look at Chis Cavanagh blog post on it.
Use as Jose mentioned the ReWritter
I can solve my problem .
you should create folder whit name Default and create page whit name default too and then use web.sitemap in navigation controls .

Resources