4

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

SamJolly
  • 6,347
  • 13
  • 59
  • 125

4 Answers4

10

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.

NightOwl888
  • 55,572
  • 24
  • 139
  • 212
  • I found the Roles attribute in the sitemap useful for menu links to external resources. it seems to work perfectly with Forms authentication. – Mattias Åslund Feb 04 '14 at 11:32
  • @MattiasÅslund - I corrected my post. The roles attribute works with Forms authentication because it was designed for ASP.NET. However, ASP.NET security is based on the file system and/or URL which is not good enough for MVC (a resource can be linked to from multiple URLs, and doesn't necessarily involve the file system), so you should only use the roles attribute for interoperability with ASP.NET. – NightOwl888 Feb 04 '14 at 15:16
1

On the SOUController, do you have the [Authorize] attribute added somewhere? MvcSiteMapProvider uses that one to determine ACL.

maartenba
  • 3,344
  • 18
  • 31
0

If you use a sitemap you can / have to (above approach did not work for me) specify the roles in the sitemap.

<mvcSiteMapNode title="Rechnungen" controller="Customer/Bills" action="Index" roles="CompanyAdmin"/>
Remy
  • 12,555
  • 14
  • 64
  • 104
  • I am not sure where you got the controller="Customer/Bills" syntax from, but it is not supported. Use area="Customer" controller="Bills" if that is in fact what you intended to do. – NightOwl888 Feb 21 '14 at 15:07
0

I just put

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

in Web.config's appSettings,like this:

<appSettings>
    <add key="webpages:Version" value="2.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="PreserveLoginUrl" value="true" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
    <add key="jqueryTheme" value="redmond" />
    <add key="MvcSiteMapProvider_IncludeAssembliesForScan" value="Cost3" />
    <add key="MvcSiteMapProvider_UseExternalDIContainer" value="false" />
    <add key="MvcSiteMapProvider_ScanAssembliesForSiteMapNodes" value="true" />

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

  </appSettings>

and put [Authorize] attribute on each of the controller or action,like this:

[Authorize(Roles = "Administrator")]
public class UserManagementController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
 }

then OK!

Andy
  • 94
  • 10