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?
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:
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: