asp.net-mvcasp.net-mvc-3mvcsitemapproviderasp.net-mvc-sitemap

How implement security with the mvcSiteMapProvider?


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


Solution

  • 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.