Fine Grain Authorization

Fine Grain Authorization

Old forum URL: forums.lhotka.net/forums/t/4880.aspx


justin.fisher posted on Wednesday, May 21, 2008

I have read several older posts on this subject but the lines between 'old way' and 'new way' seemed blurred.

I just started using CSLA and I am attempting to manage authorization.  The project tracker example seems to treat all objects as equivalent, where you can either add a project or you can't. 

I am running into many situations where I need to control access at a finer grain.  Something along the lines of granting access to a project based on some attributes within the project.  For instance if the logged on user is the owner of the object then that user should be able to edit the object regardless of their role membership.

I have looked breifly at InstanceAllow___ and this looks like the place to do things like that.  Does anyone have any experience with this? Or have any other suggestions?

ajj3085 replied on Wednesday, May 21, 2008

I think for those kinds of checks you need to override CanWriteProperty.  I think there may have been talk of being able to define AccessRules like you would your own business rule.. but I'm not sure about that or if any progress was made.

justin.fisher replied on Wednesday, May 21, 2008

Is there an equivalent method for access to the entire object?

The application I am working on controls access levels in the database using label based security.  The tables used to persist objects are exposed throuch views.  Each row in the secured table has columns to store which roles can read and edit each row and another column to store which roles can modify those permission levels.  The view uses the IS_MEMBER() SQL function to determine if that specific user should access a particular record.  Inserts and updates are handled via triggers on the view.  This ensure that all inserts, updates, and deletes are security checked prior to actually happening.

Using this method I know the users access level to a record when it comes out of the database.  I need to somehow communicate this to my business objects without breaking anything inside of CSLA.

If anyone is interested in label based security you can read some more about it here.  The method described in the linked document only controls read level access, I modified the technique to store roles permitted to edit or control the read & edit permission levels to each row. 

Any and all comments are welcome.

ajj3085 replied on Thursday, May 22, 2008

You mean each instance vs. the user can load any type of the class?  No, but what you could do is check when loading to see if the user has permissions and if not throw a SecurityException. 

Does that help?

justin.fisher replied on Thursday, May 22, 2008

Yes, each instance of a class has it's own authorization rules.  The records are filtered when they come out of the database, so a user only retrieves rows they have at least read access to.  Their specific access level is returned as an integer (enumeration) used to determine what they can do with the record (edit, change permission assignments, etc).  I need to communicate this to the UI so that it can alter the presentation to communicate the access level to the user. 

What I'm finding in CSLA is that authorization is associated with a class of objects and not an instance of an object.  Authorization has turned out to be the most difficult part of a new system I am implementing.  Compounding the difficulty is the fact that there is very little guidance out there that goes beyond securing access to an entire table or class of objects with role assignments.

There are numerous cases where this sort of thing would be extremely useful.  For instance, allowing a user to modify or cancel a request they submitted to the system.  The requesting user would have no explicit access to the object but because they 'own' the request they should be able to perform certain actions on it. 

I know I am not the first person to encounter these sorts of issues and I am really looking for some suggestions or guidance from someone who has already solved this problem in CSLA.  I have read over the expert business objects books and some threads in this forum but unfortunately I'm still at a loss.

ajj3085 replied on Thursday, May 22, 2008

Ahh I see.  Then in that case you may do well with InstanceAllowWrite.  Those are setup to be changed per instance.

justin.fisher replied on Thursday, May 22, 2008

Do you know of any documentation on InstanceAllow___?  I have searched through the eBooks and am not coming up with anything. I am looking into the csla source to try and figure it out but it is a bit overwhelming.

Additional question, can you tell me where  the rules being evaluated in the framework?

RockfordLhotka replied on Thursday, May 22, 2008

justin.fisher:

What I'm finding in CSLA is that authorization is associated with a class of objects and not an instance of an object.  Authorization has turned out to be the most difficult part of a new system I am implementing.  Compounding the difficulty is the fact that there is very little guidance out there that goes beyond securing access to an entire table or class of objects with role assignments.

CSLA .NET 3.5 supports two types of authorization

  1. Class level
  2. Property level

The Class level authorization is not per-instance, because it is at the class level. It is intended to allow the UI developer to enable/disable various UI elements based on the type of class that would be affected. Can the user create objects of type X? Edit them? Etc? These rules are available to the UI developer, and are used by the data portal.

The Property level authorization is either per-type or per-instance, though per-type is much faster and requires less memory - obviously the per-instance implementation means rules are stored and checked on a per-instance basis which requires more resources. Property level authorization is intended to allow the UI developer to enable/disable various UI elements based on whether the user is allowed to read or write to specific properties.

There's similar Method level authorization (CanExecuteMethod()) that works the same as the Property level authorization.

The Property level authorization is documented in the CSLA .NET Version 2.1 Handbook. Unfortunately the Class level authorization is new to CSLA 3.5 and so there's no documentation yet.

It sounds like you want to create an instance of an object and then decide whether the user is allowed to perform coarse-grained operations like insert/update/delete (obviously they were already able to do a create/fetch or you wouldn't have an instance).

You can do this by overriding Save() and checking the rules there, preventing the operation if it isn't legal by throwing a SecurityException.

If you want the UI to have access to this information as well, I'd recommend overriding IsSavable. IsSavable already checks the Class level authorization rules, but you could easily check your instance level rules first and only delegate to the base implementation if your rules pass. This way your UI code can always use this interface to find out if an object can be saved by using the standard IsSavable property (which is automatically handled for you by the CslaDataProvider in WPF for instance).

Copyright (c) Marimer LLC