Tags: , , | Categories: Articles, Tutorials Posted by RTomlinson on 9/3/2009 6:58 PM | Comments (10)

In Part 1 and Part 2 I covered how I went about building an authorization framework using Rhino Security. I am now going to cover how to integrate this into your domain model (business objects) and how we can use dynamic discovery for permission registration and database persistence.

In essence what I am saying here is that given the scenario whereby we have a domain object (lets use that of a Company business object, for example) we could state what available permissions that object could have. This post will therefore cover:

  • Defining permissions at an object level
  • The ability to register those permissions in the database

Defining Object Permissions

Having considered various implementations, I finally decided to go with an attribute based approach. The attribute requires the operation that you want access control over and to what level of granularity. For example, given the flexibility of the Rhino Security implementation we can use the operation convention of /BUSINESSOBJECT/OPERATION or /BUSINESSOBJECT/METHOD/OPERATION OR /BUSINESSOBJECT/PROPERTY/OPERATION.

In reality this would result in the following examples:

  • /Company/Add
  • /Company/Delete
  • /User/UserName/Set
As you can see this attribute (ACL) used below, it takes as a parameter, the operation and an enum that states what type of permission it is.

namespace MyApp.Core
{
    [ACL("/User/Add", "Restrict the ability to add new users", ACLType.ObjectLevel)]
    public class User : Entity, IUser
    {
        private IAuthorizationRepository _authRepo;
        protected User(IAuthorizationRepository authRepo) 
        {
            _authRepo = authRepo;
        }

        public User() 
        {
            _authRepo = ResolveType.Of<IAuthorizationRepository>();
        }

        [Length(6, 512)]
        [NotNullNotEmpty]
        public virtual string UserName { get; set; }

        [Length(6, 512)]
        [NotNullNotEmpty]
        public virtual string Password { get; set; }

 

Dynamic Permissions Discovery

Having created an attribute to apply the required information to an object we can use reflection to discover all of our permissions. Those permissions that have not been registered in the database can then be registered and any that no longer exist can be marked accordingly. The way that I implemented this was run this discovery in the Application_Start event of the Global.asax. Therefore whenever we start our application this process takes place and the overhead of some pretty heavy reflection is less of an issue.

This process, although sounding quote complex, is actually very very simple. I call a static Discover method that uses relflection to reflect the assembly, find those objects that the ACLAttribute has been applied to, checks whether that object is registered and if not then registers it.

public static void Discover(Castle.Windsor.IWindsorContainer Container)
{
  Assembly asm = Assembly.Load("MyApp.Core");

  Type[] types = asm.GetTypes();

  Type securityPermission = asm.GetType("MyApp.Core.Security.ACLAttribute", false);
  PropertyInfo operation = securityPermission.GetProperty("Operation");
  RegisterAssemblyTypes(Container, types, securityPermission, operation);
}

private static void RegisterAssemblyTypes(Castle.Windsor.IWindsorContainer Container, Type[] types, Type securityPermission, PropertyInfo operation)
{
  foreach (Type t in types)
  {
    object[] objs = t.GetCustomAttributes(securityPermission, false);

    foreach (object o in objs)
    {
      if (!Registered(operation.GetValue(o, null).ToString(), Container))
      {
        Register(operation.GetValue(o, null).ToString(), Container);
      }
    }
  }
}

This implementation works very well. It involves minimal work work the developer. When a new permission is required it simply means adding an attribute to the appropriate business object. This permission will then be automatically registered and will be visible within the permissions section of the application, allowing the administrator to associate a particular user with that permission to allow or deny the operation.

In the next post I will detail the how I implemented this using some nice jQuery iPhone checkboxes on top of the standard ASP.NET checkbox control.

Share or Bookmark this post…
  • del.icio.us
  • Digg
  • DotNetKicks
  • Facebook
  • Slashdot
  • StumbleUpon
  • Reddit
  • Technorati
  • TwitThis

Comments

gpangrango
gpangrango Indonesia on 9/8/2009 2:22 PM thanks for sharing....it's nice...
maybe u can share source code do u have...???
Bas ter Vrugt
Bas ter Vrugt Netherlands on 9/29/2009 9:49 PM thanx this was very helpful.
ernest
ernest on 11/6/2009 1:22 AM Hi Ryan.

Your posts about Rhino Security looks very interesting.

Thank you so much!
RTomlinson
RTomlinson United Kingdom on 1/24/2010 8:43 AM I am putting together a sample app that demonstrates my security framework. I will append to the post when it is done.
beto
beto United States on 2/3/2010 10:15 AM Do you know when your going to post your next blog post on the Permission UI service? You mentioned it on your 2nd blog post on this series. Thanks!
RTomlinson
RTomlinson United Kingdom on 2/3/2010 7:37 PM beto: I will try and write this on the weekend. Apologies for letting this one slip for so long.
kmoo01
kmoo01 United Kingdom on 2/24/2010 2:17 AM I feel like crying, I spent 3 days designing my own way of doing this...then just stumbled across this blog...

would love to see your sample app when you get a chance to post

cheers!
amyge
amyge United States on 3/25/2010 11:20 AM Ryan, are you planning to post the rest of the series soon? Looking forward to see more coming. Thanks! Amy
reg
reg Sweden on 4/8/2010 6:39 PM Great post!

+1 for the sample app!
amyge
amyge United States on 4/20/2010 11:43 AM Hi Ryan, I wonder what you do inside this method:

Register(string operation, Container c)

I was trying to add the operations to the database, but apparently it doesn't like it because the ISessionStorage is not configured yet in the application_start stage...

That made me wonder what you did to make the OPERATIONs visible to the permission-assigning page. Were you using Application variable to hold the values?

Thanks, Amy

Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading