- Inside the MvcSiteMapProvider - Part 1
- Inside the MvcSiteMapProvider - Part 2: Dynamic node providers
- Inside the MvcSiteMapProvider – Part 3: The ISiteMapVisibilityProvider
- Inside the MvcSiteMapProvider - Part 4: The IAclModule
- Inside the MvcSiteMapProvider - Part 5: The ISiteMapNodeUrlResolver
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.The default implementation actually consists of two modules, XmlRolesAclModule and AuthorizeAttributeAclModule, called in succession.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.
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.
Hi Kim,
ReplyDeleteWhen 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
Kim,
DeleteForget 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