Monday, July 12, 2010

ASP.NET MVC2 and the Enterprise Library Security Block Authorization Provider

When I first started with ASP.NET 2.0 I was intrigued by the built-in support for users and roles via the Membership Providers. Unfortunately I quickly found limitations for its use mainly due to the way that I like to structure permissions in my applications.

I overcame some of these limitations by using the Enterprise Library Security block which allowed me to set granular permissions and then roll them up into groups of permissions which map to individual roles.

I recently switched over from ASP.NET, using the MVP pattern, to ASP.NET MVC2 and again found the the way roles are mapped to be too limiting. Therefore I decided to implement my own custom AuthorizeAttribute to check for specific authorization rules using the Enterprise Library Security block.

This article assumes that you know how to use Membership and Role providers in ASP.NET and that we have a role called Administrators already configured. If you aren't familiar with these I'd suggest looking at the following article:

Examining ASP.NET's Membership, Roles, and Profile

I also assume that you know how to use the MVC2 authorization model.

The first thing to do is add a reference to the following assemblies in your MVC project:

Microsoft.Practices.EnterpriseLibrary.Security
Microsoft.Practices.EnterpriseLibrary.Security.Configuration
Microsoft.Practices.EnterpriseLibrary.Common

Next we'll have to configure the security block in the web.config. I'm also going to create a authorization rule which maps a "Can Manage Users" permission into the Administrators role.
<configuration>
<configSections>
<section name="securityConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Security.Configuration.SecuritySettings, Microsoft.Practices.EnterpriseLibrary.Security, Version=4.1.0.0" />
...
</configSections>
<securityConfiguration defaultAuthorizationInstance="RuleProvider" defaultSecurityCacheInstance="">
<authorizationProviders>
<add type="Microsoft.Practices.EnterpriseLibrary.Security.AuthorizationRuleProvider, Microsoft.Practices.EnterpriseLibrary.Security" name="RuleProvider">
<rules>
<add expression="R:Administrators" name="Can See Admin Menu" />
</rules>
</add>
</authorizationProviders>
</securityConfiguration>

Next we have to create our custom AuthorizeAttribute. This will allow us to check against the Enterprise Library Security block. We can do this by inheriting from the standard AuthorizeAttribute and overriding the AuthorizeCore method.
  public class AuthorizeRule : AuthorizeAttribute
{
public string Rule { get; set; }

protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (string.IsNullOrEmpty(Rule))
{
throw new InvalidOperationException("Rule not specified");
}

if (!httpContext.User.Identity.IsAuthenticated)
{
return false;
}

IAuthorizationProvider auth = AuthorizationFactory.GetAuthorizationProvider();
return auth.Authorize(httpContext.User, Rule);
}
}

Finally we mark up the appropriate controller method that you want to secure just as we would using the AuthorizeAttribute.
[AuthorizeRule(Rule = "Can Manage Users")]
public void Index()
{
...
}

It's as easy as that.

No comments:

Post a Comment