How implement security with the mvcSiteMapProvider?

SamJolly picture SamJolly · Aug 23, 2013 · Viewed 8.9k times · Source

I need to implement Role security with my mvcSiteMapProvider V4 software. I am using it with MVC3.

Example mvcSiteMap Code:

      <mvcSiteMapNode roles="Admin" title="Your Subscription (All Users)" controller="SOU" action="ListSubscribers">

This roles attribute value has no effect:

      <mvcSiteMapNode roles="NoAdmin" title="Your Subscription (All Users)" controller="SOU" action="ListSubscribers">

This is the same. I would expect the above to not work if the Admin was logged in? I would expect the first example to work if only the user was logged in.

... But no effect .

Many thanks

Answer

NightOwl888 picture NightOwl888 · Aug 25, 2013

Security trimming is not enabled by default. The first thing you need to do is turn it on.

Internal DI (web.config):

<add key="MvcSiteMapProvider_SecurityTrimmingEnabled" value="true"/>

External DI (in MvcSiteMapProvider module):

bool securityTrimmingEnabled = true; // First line in the module

Then you should put the MVC [Authorize] attribute on each of the action methods that you want to secure. In MVC4+, you can also put it at the controller level or register it globally and then use the [AllowAnonymous] attribute to selectively allow action methods to be allowed by non-authenticated users.

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new AuthorizeAttribute());
    }
}

[Authorize(Roles="Admin,Manager")]
public class MyController
{
    // Everyone has access
    [AllowAnonymous]
    public ActionResult Index()
    {
        return View();
    }

    // Only Admin and Manager roles have access, everyone else is denied
    public ActionResult About()
    {
        return View();
    }
}

The roles attribute in the XML is for backward compatibility with ASP.NET. For MVC, the only real security is using the [Authorize] attribute (or by inheriting it for your own scheme) because it is the only way to guarantee the resource cannot be accessed via an alternate route.