Security Trimming with Menu Adapter

Nov 10, 2008 at 11:55 PM
Hi All,

I am hoping that someone out there knows and has a solution to the CSS Freindly Menu Adapter NOT working with "securityTrimmingEnabled" set to "true". The minute I set this attribute on the SiteMap Provider to true none of my menus show up. If I set it back to "false" they all appear as normal; however, I don't get the ability to hide those nodes that are not supposed to be displayed. Anyone out there that may have experienced this problem and has a solution would greatly be appreciated.
Nov 11, 2008 at 12:32 AM
This is probably not a help, but I'm using security trimming enabled with the CSS Friendly menu adapters, and it works just fine.

That is, it works just fine when I view the pages at http://localhost/whateverFolder/page.aspx

When I try to view them from within VS 2008 (browse with internal browser or an external browser), I don't see the menus.

Could that be your problem?
Nov 11, 2008 at 2:05 AM
So, I am a little confused as to what is the difference between what you are saying above. When you view the page "http://localhost/whateverFolder/page.aspx you are using an internal browser or an external browser). So what's the difference?
Nov 11, 2008 at 5:17 PM
The difference is how I view the page.

1. Open the browser, type in http://localhost/default.aspx

2. From inside VS2008, right-click on the page and select View in Browser from the context menu, or right-click on a file in the solution explorer window and select View in Browser or Browse With...

Option 1, I see the menu.

Option 2, I don't.
Nov 11, 2008 at 6:31 PM
That is what I thought you meant, but just wanted to make sure. In either case, it does not work for me in either scenario. Would you happen to have a simple example of your code setup. Maybe it is something I have mis-configured?
Nov 11, 2008 at 6:45 PM
Unfortunately, there's nothing "simple" about our code set-up... We've got nested master pages, with the menu embedded as a user control in the secondary master page.

Maybe there's something wrong with how you have your permissions set up in web.config? Maybe somehow you're excluding all the pages that would normally be showing up in the menu.

Can you show us the relevant parts of your web.config file?
Nov 11, 2008 at 6:50 PM
------ START web.config -------
<?xml version="1.0"?>
<!--
    Note: As an alternative to hand editing this file you can use the
    web admin tool to configure settings for your application. Use
    the Website->Asp.Net Configuration option in Visual Studio.
    A full list of settings and comments can be found in
    machine.config.comments usually located in
    \Windows\Microsoft.Net\Framework\v2.x\Config
-->
<configuration>
    <appSettings/>
    <connectionStrings>
    </connectionStrings>
    <system.web>
  <pages theme="Default"></pages>
        <!--
            Set compilation debug="true" to insert debugging
            symbols into the compiled page. Because this
            affects performance, set this value to true only
            during development.
        -->
        <compilation debug="true">
        </compilation>
        <!--
            The <authentication> section enables configuration
            of the security authentication mode used by
            ASP.NET to identify an incoming user.
        -->
        <authentication mode="Forms">
            <forms loginUrl="~/Security/Login.aspx" name=".ASPXFORMSAUTH"></forms>
        </authentication>
        <authorization>
            <deny users="?"/>
        </authorization>
        <!--
            The <customErrors> section enables configuration
            of what to do if/when an unhandled error occurs
            during the execution of a request. Specifically,
            it enables developers to configure html error pages
            to be displayed in place of a error stack trace.

        <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
            <error statusCode="403" redirect="NoAccess.htm" />
            <error statusCode="404" redirect="FileNotFound.htm" />
        </customErrors>
        -->
        <!--
            Membership and Role provider configuration
        -->
        <roleManager enabled="true">
            <providers>
                <clear/>
                <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
                     connectionStringName="DBSecurityConnectionString"
                     applicationName="DanosIntranet"/>
            </providers>
        </roleManager>
        <membership>
            <providers>
                <clear/>
                <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
                     connectionStringName="DBSecurityConnectionString"
                     applicationName="DanosIntranet"/>
            </providers>
        </membership>
        <siteMap enabled="true">
            <providers>
                <clear/>
                <add name="AspNetXmlSiteMapProvider" type="System.Web.XmlSiteMapProvider" siteMapFile="Web.sitemap" securityTrimmingEnabled="false"/>
            </providers>
        </siteMap>
    </system.web>
</configuration>

------------ END web.config -------------

------------ START web.sitemap -------------
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
    <siteMapNode url="" title="" description="">
        <siteMapNode url="" title="HOME" description="">
            <siteMapNode url="~/Home/Home_1.aspx" title="HOME_1" description=""></siteMapNode>
            <siteMapNode url="~/Home/Home_2.aspx" title="HOME_2" description=""></siteMapNode>
            <siteMapNode url="~/Home/Home_3.aspx" title="HOME_3" description=""></siteMapNode>
        </siteMapNode>
        <siteMapNode url="" title="PERSONAL" description="">
            <siteMapNode url="~/Personal/Personal_1.aspx" title="PERSONAL_1" description=""></siteMapNode>
            <siteMapNode url="~/Personal/Personal_2.aspx" title="PERSONAL_2" description=""></siteMapNode>
            <siteMapNode url="~/Personal/Personal_3.aspx" title="PERSONAL_3" description=""></siteMapNode>
        </siteMapNode>
        <siteMapNode url="" title="APPLICATIONS" description="">
            <siteMapNode url="~/Applications/Applications_1.aspx" title="APPLICATIONS_1" description=""></siteMapNode>
            <siteMapNode url="~/Applications/Applications_2.aspx" title="APPLICATIONS_2" description=""></siteMapNode>
            <siteMapNode url="~/Applications/Applications_3.aspx" title="APPLICATIONS_3" description=""></siteMapNode>
        </siteMapNode>
        <siteMapNode url="" title="DOCUMENTS" description="">
            <siteMapNode url="~/Documents/Documents_1.aspx" title="DOCUMENTS_1" description=""></siteMapNode>
            <siteMapNode url="~/Documents/Documents_2.aspx" title="DOCUMENTS_2" description=""></siteMapNode>
            <siteMapNode url="~/Documents/Documents_3.aspx" title="DOCUMENTS_3" description=""></siteMapNode>
        </siteMapNode>
        <siteMapNode url="" title="FORUM" description="">
            <siteMapNode url="~/Forum/Forum_1.aspx" title="FORUM_1" description=""></siteMapNode>
            <siteMapNode url="~/Forum/Forum_2.aspx" title="FORUM_2" description=""></siteMapNode>
            <siteMapNode url="~/Forum/Forum_3.aspx" title="FORUM_3" description=""></siteMapNode>
        </siteMapNode>
        <siteMapNode url="" title="IT" description="">
            <siteMapNode url="~/IT/IT_1.aspx" title="IT_1" description=""></siteMapNode>
            <siteMapNode url="~/IT/IT_2.aspx" title="IT_2" description=""></siteMapNode>
            <siteMapNode url="~/IT/IT_3.aspx" title="IT_3" description=""></siteMapNode>
        </siteMapNode>
        <siteMapNode url="" title="QUALITY" description="">
            <siteMapNode url="~/Quality/Quality_1.aspx" title="QUALITY_1" description=""></siteMapNode>
            <siteMapNode url="~/Quality/Quality_2.aspx" title="QUALITY_2" description=""></siteMapNode>
            <siteMapNode url="~/Quality/Quality_3.aspx" title="QUALITY_3" description=""></siteMapNode>
        </siteMapNode>
        <siteMapNode url="" title="SAFETY" description="">
            <siteMapNode url="~/Safety/Safety_1.aspx" title="SAFETY_1" description=""></siteMapNode>
            <siteMapNode url="~/Safety/Safety_2.aspx" title="SAFETY_2" description=""></siteMapNode>
            <siteMapNode url="~/Safety/Safety_3.aspx" title="SAFETY_3" description=""></siteMapNode>
        </siteMapNode>
        <siteMapNode url="" title="POLICY" description="">
            <siteMapNode url="~/Policy/Policy_1.aspx" title="POLICY_1" description=""></siteMapNode>
            <siteMapNode url="~/Policy/Policy_2.aspx" title="POLICY_2" description=""></siteMapNode>
            <siteMapNode url="~/Policy/Policy_3.aspx" title="POLICY_3" description=""></siteMapNode>
        </siteMapNode>
        <siteMapNode url="" title="CRM" description="">
            <siteMapNode url="~/CRM/CRM_1.aspx" title="CRM_1" description=""></siteMapNode>
            <siteMapNode url="~/CRM/CRM_2.aspx" title="CRM_2" description=""></siteMapNode>
            <siteMapNode url="~/CRM/CRM_3.aspx" title="CRM_3" description=""></siteMapNode>
        </siteMapNode>
    </siteMapNode>
</siteMap>

------------- END web.sitemap -----------------


Nov 11, 2008 at 6:51 PM
Note: "securityTrimmingEnabled" in the web.config above is currently set to "false" so that I continue testing. Setting this to "true" causes the menu to completely disappear.
Nov 11, 2008 at 7:33 PM
I think your site is behaving exactly the way you're telling it to ;-)

        <authorization>
            <deny users="?"/>
        </authorization>

You're saying, "Deny access to all unauthorized users."

So until you log in, you won't see any pages in the menu.

(which makes it kind of hard to log in unless your default page is also your log-in page, and you only have protected pages on the site)

Here's a sample from our web.config:

  <location path="downloads/default.aspx">
    <system.web>
      <authorization>
        <deny users="?"/>
        <allow users="*"/>
      </authorization>
    </system.web>
  </location>
  <location path="downloads/login.aspx">
    <system.web>
      <authorization>
        <allow users="?"/>
        <deny users="*"/>
      </authorization>
    </system.web>
  </location>


This says that for the default downloads page, only logged-in users can see it. And only users who aren't logged in can see the log-in page.

Then in the <forms> section, I have this:

<forms loginUrl="downloads/login.aspx" defaultUrl="downloads/default.aspx" slidingExpiration="true" ></forms>

This says, if someone who's not logged in tries to access downloads/default.aspx, he should be sent to downloads/login.aspx. And then once he's logged in, he goes to downloads/default.aspx

And in the web.sitemap file, I would have something like this:

    <siteMapNode url="downloads/login.aspx" title="Log In" description="" />
    <siteMapNode url="downloads/default.aspx" title="Downloads" description="" />

Users who aren't logged in will see the first node, but not the second. Users who ARE logged in will see the second, but not the first.

Make sense?





Nov 12, 2008 at 8:28 PM
Thanks for your reply; however, I am still having problems and I am pretty sure is just the combination I am using. I'll try to keep it simple and not show everything in hopes that maybe you can help me find out where the problem may be.

At the root of the website I have a "Default.aspx" file which has the following content:

------------------------ START:  Default.aspx -------------------------
<%@ Page Title="" Language="C#" MasterPageFile="~/Home.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<h1>HOME PAGE</h1>
</asp:Content>
------------------------ END: Default.aspx -------------------------

At the root of the website I have a "Web.sitemap" file which has the following content:

------------------------- START: Web.sitemap ---------------------
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
    <siteMapNode url="" title="" description="">
           <siteMapNode url="~/Personal/Default.aspx" title="PERSONAL" description="">
                   <siteMapNode url="~/Personal/Personal_1.aspx" title="PERSONAL_1" description=""></siteMapNode>
                   <siteMapNode url="~/Personal/Personal_2.aspx" title="PERSONAL_2" description=""></siteMapNode>
                  <siteMapNode url="~/Personal/Personal_3.aspx" title="PERSONAL_3" description=""></siteMapNode>
           </siteMapNode>
        <siteMapNode url="~/Applications/Default.aspx" title="APPLICATIONS" description="">
            <siteMapNode url="~/Applications/Applications_1.aspx" title="APPLICATIONS_1" description=""></siteMapNode>
            <siteMapNode url="~/Applications/Applications_2.aspx" title="APPLICATIONS_2" description=""></siteMapNode>
            <siteMapNode url="~/Applications/Applications_3.aspx" title="APPLICATIONS_3" description=""></siteMapNode>
        </siteMapNode>
    </siteMapNode>
</siteMap>
------------------------- END: Web.sitemap ---------------------

I have two folders at the root of the website, one named "Personal" and one named "Applications". These folders are to mimic the hierarchy shown in the Web.sitemap file above. The "Personal" folder contains a "Default.aspx", "Personal_1.aspx", "Personal_2.aspx", "Personal_3.aspx", and "web.config" file. All the ".aspx" files are simply content holders for that portion of the site. The "web.config" file contains the authorization rules for that folder. I show the "web.config" file within the "Personal" folder below. The "Applications" has the exact same setup.

Notice that what I am doing in the web.config file for the "Personal" folder is ensuring that noone has access that is not yet logged in and if you are logged in only those that are part of the specific role will have access.

-------------------------- START: web.config file in the Personal folder ------------------------
<?xml version="1.0"?>
<!--
    Note: As an alternative to hand editing this file you can use the
    web admin tool to configure settings for your application. Use
    the Website->Asp.Net Configuration option in Visual Studio.
    A full list of settings and comments can be found in
    machine.config.comments usually located in
    \Windows\Microsoft.Net\Framework\v2.x\Config
-->
<configuration>
    <appSettings/>
    <connectionStrings/>
    <system.web>
        <authorization>
            <deny users="?"/>
            <deny roles="Applications,CRM,Documents,Forum,Home,IT,Policy,Quality,Safety"/>
            <allow roles="Personal"/>
        </authorization>
    </system.web>
</configuration>
-------------------------- END: web.config file in the Personal folder ------------------------

Finally here is my current web.config file at the root of the website

-------------------------- START: web.config file at root of site -----------------------------
<?xml version="1.0"?>
<!--
    Note: As an alternative to hand editing this file you can use the
    web admin tool to configure settings for your application. Use
    the Website->Asp.Net Configuration option in Visual Studio.
    A full list of settings and comments can be found in
    machine.config.comments usually located in
    \Windows\Microsoft.Net\Framework\v2.x\Config
-->
<configuration>
    <appSettings/>
    <connectionStrings>
    </connectionStrings>
    <system.web>
        <pages theme="Default"></pages>
        <!--
            Set compilation debug="true" to insert debugging
            symbols into the compiled page. Because this
            affects performance, set this value to true only
            during development.
        -->
        <compilation debug="true">
        </compilation>
        <!--
            The <authentication> section enables configuration
            of the security authentication mode used by
            ASP.NET to identify an incoming user.
        -->
        <authentication mode="Forms">
            <forms loginUrl="~/Security/Login.aspx" name=".ASPXFORMSAUTH"></forms>
        </authentication>
        <!--
            The <customErrors> section enables configuration
            of what to do if/when an unhandled error occurs
            during the execution of a request. Specifically,
            it enables developers to configure html error pages
            to be displayed in place of a error stack trace.

        <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
            <error statusCode="403" redirect="NoAccess.htm" />
            <error statusCode="404" redirect="FileNotFound.htm" />
        </customErrors>
        -->
        <!--
            Membership and Role provider configuration
        -->
        <roleManager enabled="true">
            <providers>
                <clear/>
                <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
                     connectionStringName="DBSecurityConnectionString"
                     applicationName="DanosIntranet"/>
            </providers>
        </roleManager>
        <membership>
            <providers>
                <clear/>
                <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
                     connectionStringName="DBSecurityConnectionString"
                     applicationName="DanosIntranet"/>
            </providers>
        </membership>
        <siteMap enabled="true">
            <providers>
                <clear/>
                <add name="AspNetXmlSiteMapProvider" type="System.Web.XmlSiteMapProvider" siteMapFile="Web.sitemap" securityTrimmingEnabled="true"/>
            </providers>
        </siteMap>
    </system.web>
</configuration>
-------------------------- END: web.config file at root of site -----------------------------

Now, when I have "securityTrimmingEnabled" set to False I get the effect of if I click on a menu item for which I am currently not within that role it brings up the Login Form and asks me to login. If I then login as someone having that role, the proper sub-menus are displayed. However, ALL sub-menus are displayed and NOT only those that I have access to. Thus the reason I wanted to enable Security Trimming.

However, when I enable Security Trimming the menu totally disappears. I have NO primary navigation at all.
Nov 12, 2008 at 8:48 PM
1. Does the security trimming work when you're NOT using the CSS Friendly control adapters? That is, are you sure this problem is related to the control adapters?

2. Try putting the allow/deny stuff in the root web.config, using the appropriate paths to the pages that need/don't need protection.
Feb 15, 2010 at 7:53 PM

I'm having this problem also, did anyone find a fix?

Apr 8, 2010 at 8:07 PM

try this:

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
    <siteMapNode url="" title="" description=""
roles”*”>