views:

54

answers:

3

Within my logic layer I have the need to check permissions for a wide variety of actions. Some actions are generic but some are highly specialized. Each action has a corresponding permission hierarchy that is evaluated prior to performing the action. I have been tossing around architecture ideas in my head but haven't reached a solid one that I think will be extensible, simple and elegant.

The current code looks something like this:

public class LogicObject
{
       public void Add()
       {
            Check Add Permission
            Perform
       }
       public void Update()
       {
            Check Update Permission
            Perform
       }
}

The problem with this architecture is that, first it isn't really all that extensible, and second it doesn't allow me to check the permission without performing the action.

Another idea I had was to have something like this:

public class AddAction : IAction
{
   public bool IsPermitted;
   public void Perform();
}

public class LogicObject
{
   public IAction AddAction {get { return new AddAction(); } }
}

I like this architecture better but I am not quite set on it. It seems a bit hokey. I can't imagine that this type of architecture is unique. What are some examples of a better way of doing this?

+2  A: 

Another option you have is to use Aspect Oriented Programming to have a components external from your services to control the method access authorization. What it basically means is that your methods will be wrapped in runtime by code that will perform the authorization.

An example solution for implementing this for java is Spring Security which will give you a multitude of ways to customize and define your authorization scheme. The object would then look something like:

public class logicObject {
     @PreAuthorize("hasRole('ROLE_USER')")
           public void update() {
                //Perform
           }

     //...
    }

Off course you will need additional code to define the security context and create a proxy for the logicObject class with that context, along with defining your authorization itself.

Since it seems like the code example you gave is in C# you might want to have a look at Role Based Security, and all the goods in [System.Security.Permissions][2] namespace. It allows you to use attributes to control the access of a method in run time. You can define your own custom attributes and authorization provider. Using it might look something like:

public class LogicObject
{
    [PrincipalPermissionAttribute(SecurityAction.Demand, Role="ROLE_USER")]
       public void Add()
       {
            //Perform
       }

}
Amitay Dobo
A: 

I don't think your first example was that far off; I'd split the logic in half: have the externally visible class members as a facade - seperate from the inner (private members) that actually do the work. The outside facades job is therefore to accpet the function call, perform a security check and respond as appropriate. This would also mean you had a consistent approach as to where the security check was done.

Another option you might want to look into is the Microsoft Enterprise Libraries, as they have security blocks which cover that sort of thing. You get a security framework for free (which stands a high chance of being a good fit if you're in the MS camp), and there will be example code which will cover your question in some detail.

I'm not sure off had where the extended documentation is: Tom Hollanders blog may be a place to look, otherwise you can get the EntLibs from CodePlex.

Adrian K
A: 

It looks like you are using C# styling here so a possible .Net approach to the problem is to attach an attribute to the method the defines the permission required to execute the method, using your example:

public class LogicObject
{
       [PrincipalPermission(Security.Demand, Role="AddItem")]
       public void Add()
       {
            Perform
       }
       [PrincipalPermission(Security.Demand, Role="AddItem")]
       public void Update()
       {
            Perform
       }
}

PrincipalPermission checks the Thread.CurrentPrincipal user to see if the user has rights to the action in question. I've also built custom attributes that have similar functions but deal more with row-level security instead of general rights or permissions.

The advantage of using an attribute is that you can code it once and the code applies to every consumer of the attribute, as opposed to writing the logic over and over again.

thaBadDawg
Apparently I should have read Amitay Dobo's completely before posting. Saw the java code in the first example and skipped over the rest of it. My bad.
thaBadDawg