Tuesday, April 10, 2012

Inside the MvcSiteMapProvider - Part 4: The IAclModule

The IAclModule extension point in , are just like the ISiteMapVisibilityProvider very useful and easily implemented. It allows you to control which nodes are accessible to users. The default module checks for [Authorize] attributes on action methods and the roles attribute defined in the sitemap XML. The documentation lacks some information about the role attribute, and some about the creation of the actual module, this will be addressed in this post.

Internals

Firstly it is important to know that for any IAclModule to be used, security trimming must be enabled in the web.config, otherwise correctly implemented modules will always return true. The reason for this that all modules in theory should check if security trimming is enabled, but this is not enforce in the current version, 3.2.2, meaning that it depends on the module implementation. But all modules included checks if security trimming is enabled.

Performance Tip: If you don’t need security trimming, disable it. It can seriously kill performance with many nodes, at least with the default implementation.

Update: My pull request to enforce the security trimming check before the ACL modules are called has been accepted and merged into the master branch. So in the next version you won’t have to manually check it in the module.

The default implementation actually consists of two modules, XmlRolesAclModule and AuthorizeAttributeAclModule, called in succession.

XmlRolesAclModule

This ACL module allows you to define which role has access to a node. The roles are defined in the sitemap XML using the roles attribute like this:
Multiple roles can be separated by a comma. A star means authenticated users, a question mark means unauthenticated users and a string defines the name of the role needed to access this node.

AuthorizeAttributeAclModule

Basically use the [Authorize] attribute from ASP.NET MVC to check for access. This is by far the most expensive ACL module provided with MvcSiteMapProvider.
Tip: This module also works with custom attributes derived from AuthorizeAttribute

Custom ACL modules

Creating a custom ACL module is easy. Just created a new class implementing the IAclModule interface, and define it in either the web.config or by using dependency injection.
A basic ACL module which just checks if the a user is authenticated could look like this:
The method IsAccessibleToUser, takes the following parameters:
controllerTypeResolver : IControllerTypeResolver
This is an interface used to resolve the type of a controller.
provider : DefaultSiteMapProvider
The sitemap provider used.
context : HttpContext
The current HttpContext.
node : SiteMapNode
The node to check.

22 comments:

  1. Hi Kim,

    When you say: "This module also works with custom attributes derived from AuthorizeAttribute"...

    I have a custom Authorize attribute that's derived from the Authorize attribute and it's not working out of the box. Why?

    Here's the code:

    public class PermissionAttribute : AuthorizeAttribute
    {
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {

    //return true or false depending on database checks
    }
    }

    This is applied as Global filter.

    Hope you get the idea.

    I think I'll have to implement a custom AclModule.

    Thanks for the post. It really helps!

    Leniel

    ReplyDelete
    Replies
    1. Kim,

      Forget about the previous comment.

      What I was looking for was a way of extending the VisibilityProvider. You discusses about it in part 3: http://xharze.blogspot.com.br/2012/04/inside-mvcsitemapprovider-part-3.html

      Now my nodes are being hidden according to my custom rules and everything works as expected.

      Thank you very much for this great series!

      All the best,

      Leniel

      Delete
  2. there is lot of information in Ur blog,thanks for the article,i hope upcoming article give us latest updates,
    https://www.apponix.com/Java-Institute/Java-Training-Institute-in-Bangalore.html

    ReplyDelete