maartenba / MvcSiteMapProvider

An ASP.NET MVC SiteMapProvider implementation for the ASP.NET MVC framework.
Microsoft Public License
537 stars 220 forks source link

custom route and security trimming #449

Closed ste22g closed 7 years ago

ste22g commented 7 years ago

Hi, using a custom route with security trimming enabled, the menu lines are always displayed regardless of by the attribute set in the controller method security. Where the custom route is not used it all works correctly. In the code below the Menu "A" working properly while the "B" and "C" menus are always displayed. The AuthorizeIsAdminLevel attribute inherits from AuthorizeAttribute and is the same used in all controllers.

config:

<add key="MvcSiteMapProvider_UseExternalDIContainer" value="false" />
<add key="MvcSiteMapProvider_ScanAssembliesForSiteMapNodes" value="false" />
<add key="MvcSiteMapProvider_SecurityTrimmingEnabled" value="true" />
<add key="MvcSiteMapProvider_VisibilityAffectsDescendants" value="false" />
<add key="MvcSiteMapProvider_DefaultSiteMapNodeVisibiltyProvider" value="MvcSiteMapProvider.FilteredSiteMapNodeVisibilityProvider, MvcSiteMapProvider" />
<add key="MvcSiteMapProvider_AttributesToIgnore" value="cssclass" />

sitemap:

<mvcSiteMapNode title="Menu" clickable="false" visibilityProvider="MvcSiteMapProvider.TrimEmptyGroupingNodesVisibilityProvider, MvcSiteMapProvider" >
    <mvcSiteMapNode title="Menu A" clickable="false" visibilityProvider="MvcSiteMapProvider.TrimEmptyGroupingNodesVisibilityProvider, MvcSiteMapProvider" >
        <mvcSiteMapNode title="Title A1" controller="CtrA" action="Act1" />
        <mvcSiteMapNode title="Title A2" controller="CtrA" action="Act2" />
    </mvcSiteMapNode>
    <mvcSiteMapNode title="Menu B" clickable="false" visibilityProvider="MvcSiteMapProvider.TrimEmptyGroupingNodesVisibilityProvider, MvcSiteMapProvider" >
        <mvcSiteMapNode title="Title B1" controller="CtrB" action="Act1" target="TarB" route="RouteB" />
        <mvcSiteMapNode title="Title B2" controller="CtrB" action="Act2" target="TarB" route="RouteB"/>
    </mvcSiteMapNode>
    <mvcSiteMapNode title="Menu C" clickable="false" visibilityProvider="MvcSiteMapProvider.TrimEmptyGroupingNodesVisibilityProvider, MvcSiteMapProvider" >
        <mvcSiteMapNode title="Title C1" controller="CtrB" action="Act1" target="TarC" route="RouteB" />
        <mvcSiteMapNode title="Title C2" controller="CtrB" action="Act2" target="TarC" route="RouteB"/
    </mvcSiteMapNode>
</mvcSiteMapNode>

route:

routes.MapRoute(
                 name: "RouteB",
                 url: "CtrB/{action}/{target}/{id}/{sectionId}/{itemId}",
                 defaults: new { controller = "CtrB", action = "Index", id = UrlParameter.Optional, sectionId = UrlParameter.Optional, itemId = UrlParameter.Optional }
             );

controllers:

[AuthorizeIsAdminLevel]
public class CtrAController : Controller
{
    public ActionResult Act1(int id)
    {
         return View();
    }

    ... other method
}

[AuthorizeIsAdminLevel]
public class CtrBController<T> : CustomController where T : CustomModel
{      
    private IManager<T> man;

    public CtrBController(string target)
    {
        man = ManagerFactory.CreateInstance<T>(target);
    }

    public ActionResult Act1(string target, int id)
    {
        ResultModel<T> result = man.Read(id);
        return View(result.Value);
    }

    ... other method
}

Thank you as of now who can help me.

ste22g

NightOwl888 commented 7 years ago

Hi, and sorry for the delayed reply. It's not clear what your question is exactly, since routing and security are two separate and unrelated concerns.

I did notice that you have your route misconfigured, though. The route class only supports one optional route parameter and it must be the right-most parameter. It will work for incoming routes, but it won't be able to work out what to do when generating the URL if you don't supply all of the parameters. To fix this, you should have multiple routes...

routes.MapRoute(
    name: "RouteB",
    url: "CtrB/{action}/{target}/{id}/{sectionId}/{itemId}",
    defaults: new { controller = "CtrB", itemId = UrlParameter.Optional }
);

routes.MapRoute(
    name: "RouteB-2",
    url: "CtrB/{action}/{target}/{id}",
    defaults: new { controller = "CtrB", Id = UrlParameter.Optional }
);

routes.MapRoute(
    name: "RouteB-3",
    url: "CtrB/{action}",
    defaults: new { controller = "CtrB", action = "Index" }
);

My guess is the misconfigured routing is taking you to the wrong action method, so the security in turn is not getting executed.

ste22g commented 7 years ago

Thank's a lot.

ste22g