Sunday, September 13, 2009

Permission Granted

If you are working on a real world project chances are so high that authentication (who can access the system) and authorization (what he has permission to do)are among its non-functional requirements.
Authentication is somehow straight forward . There are a lot of approaches and patterns we can stick to but when it comes to authorization it's not that simple. The problem is people can have permission to perform an action globally or to perform it on some objects so whenever we want to check if somebody can do something we should check 1.the action and if necessary 2.the object that is acted upon.
Checking the action itself can be done by hard coding the action names in regarding methods so that every time a method is called it says if you want to run me you should have a XXXX permission but checking objects can't be hard coded and should be retrieved in run time therefore we should have a way to tell our program where to find the object.

Here's a solution that we are using on our projects and I'd like to share it with you:
Database:
We keep these information in a table:
  • Source (Who granted this permission)
  • Target(To whom this permission is granted)
  • Action(What action is granted)
  • Context(the action is granted on this context ,it can be a global definition or a type of an object or id of an object)
  • Type (if it's granted or denied )
Domain Model:
in our domain model we have this PermissionAttribute to mark a method so that whenever we want to run it ,its permission should be checked.

for example if there a AddFolder method and user should have a AddFolder permission we write it as follows:

[Permission(Action="AddFolder",Context="Folder")]
public void AddFolder(Folder folder)
{

}
Then we know that every user who wants to run this method should have an "AddFolder" permission on Folder context but what if we want to check if he can add a folder to a specific folder here's what we do :
[Permission(Action="AddFolder",Context="Folder")]
[Permission(Action="AddFolder"
,ContextLookup="folder.ParentFolder.Id")]
public void AddFolder(Folder folder)
{

}

It says that not only user should have a permission to AddFolder generally but also
should have a AddFolder permission on ParentFolder.

How it works :
Finally we have this security checker interceptor in place that runs before a method
is called and check to see if there's a permissoin attribute has set and
if there's a ContextLookup is available it gets object information query over
granted permissions and throws an exception if permission is not granted or is denied.

Well that's all folks :)

No comments: