ridermansb
ridermansb

Reputation: 11069

Deny node has visible

When running the command @Html.MvcSiteMap().Menu(false) all nodes (even those who are denied access) are displayed.

As an example I have the controller Financeiro

[Authorize(Roles = "Financeiro")]
public class homeController : baseController
{
    public ActionResult index()
    {
        return View();
    }
}

In Mvc.sitemap

<mvcSiteMapNode title="Financeiro" roles="Financeiro" area="Financeiro" clickable="false">
    <mvcSiteMapNode title="Contas" controller="contas" action="index">
        <mvcSiteMapNode title="Nova conta" action="novo" changeFrequency="Never" btnClass="btn-primary"  />
    </mvcSiteMapNode>
    <mvcSiteMapNode title="Categorias" controller="categorias" action="index" />
    <mvcSiteMapNode title="A Pagar" controller="apagar" action="index" description="Contas a pagar" />
    <mvcSiteMapNode title="A Receber" controller="areceber" action="index" description="Contas a receber" />
</mvcSiteMapNode>

Ninject

I use Ninject, and installed package MvcSiteMapProvider.MVC4.DI.Ninject.Modules

In file MvcSiteMapProviderModule.cs

this.Kernel.Bind<ISiteMapNodeVisibilityProviderStrategy>().To<SiteMapNodeVisibilityProviderStrategy>()
    .WithConstructorArgument("defaultProviderName", "MvcSiteMapProvider.FilteredSiteMapNodeVisibilityProvider, MvcSiteMapProvider");

Packages

MvcSiteMapProvider.MVC4 4.0.6
MvcSiteMapProvider.MVC4.Core 4.0.6
MvcSiteMapProvider.MVC4.DI.... 4.0.6 MvcSiteMapProvider.Web 4.0.6

When a user (with or without Financiero role) accesses the system, the node is displayed

Upvotes: 1

Views: 365

Answers (1)

NightOwl888
NightOwl888

Reputation: 56909

Did you enable security trimming in your Ninject MvcSiteMapProviderModule.cs file? The default configuration has a variable at the top of the file.

bool securityTrimmingEnabled = false;

It is injected into the SiteMapBuilderSet near the end of the file:

// Configure the builder sets
this.Kernel.Bind<ISiteMapBuilderSet>().To<SiteMapBuilderSet>().Named("siteMapBuilderSet1")
    .WithConstructorArgument("instanceName", "default")
    .WithConstructorArgument("securityTrimmingEnabled", securityTrimmingEnabled)
    .WithConstructorArgument("enableLocalization", enableLocalization)
    .WithConstructorArgument("siteMapBuilder", this.Kernel.Get<ISiteMapBuilder>("compositeSiteMapBuilder"))
    .WithConstructorArgument("cacheDetails", this.Kernel.Get<ICacheDetails>("cacheDetails1"));

You need to change this to true in order for the security features to function.

About the Exception:

One possible workaround is to disable the AuthorizeAttributeAclModule in your DI config, as it looks like you are only using the XmlRolesAclModule:

// Before
        // Configure Security
        this.Kernel.Bind<AuthorizeAttributeAclModule>().ToSelf();
        this.Kernel.Bind<XmlRolesAclModule>().ToSelf();
        this.Kernel.Bind<IAclModule>().To<CompositeAclModule>()
            .WithConstructorArgument("aclModules", 
                new IAclModule[] { 
                    this.Kernel.Get<AuthorizeAttributeAclModule>(), 
                    this.Kernel.Get<XmlRolesAclModule>() 
                });

// After
        // Configure Security
        this.Kernel.Bind<XmlRolesAclModule>().ToSelf();
        this.Kernel.Bind<IAclModule>().To<XmlRolesAclModule>();

But that is only side-stepping the problem, and you shouldn't do this if you are using the Authorize attribute or similar filters.

I have never seen a configuration that would cause AuthroizeAttributeAclModule to throw an exception before, I would really like to take a look at why this is happening. Can you build a demo and open an issue @ GitHub?

Upvotes: 2

Related Questions