An OO Roles Based Security Model
It is a fairly standard roles based security system where any give user can have 0..n roles and any role can be assigned to 0..n users. From an object perspective a user hasmany (optional) roles and a role hasmany (optional) users. From a db perspective, there is a UsertoRole joining table. So far, so standard.
A role can have 0..n permissions (0 to allow for roles to be created before their permissions are associated). Each permission is just associated to a single role. Usually two roles will never have the same permission (if they do it should often be refactored out into a different role), but if two roles do have identical permissions, it would simply result in two identical permission records as there is no need to support a many to many relationship between roles and permissions.
A permission is associated to an object (or “all”), an action list (or “all”) and an optional filter for the edge cases that need it. So, if you have the ability to add and edit all users, Object=User, ActionList=add,edit and filter is null. If you can only delete products under $5 (it could happen!) Object=Product, ActionList=Delete and Filter is Price < 5.
The object relates to a specific business object and the action to a public method name available in that objects service layer (not the controller, as security roles should not be controller specific – they’re fundamental to the model).
Are other people doing something similar? Any thoughts/comments on the approach?



Good question. I actually treat roles almost as a synonym for groups as my specification process is based on roles and the tasks those roles have to perform, so I haven't usually needed an additional level of indirection. Of course a role is assigned 0..n permissions so a "site reviewer" role might have a bunch of different permissions, and a user can be assigned multiple roles if they are both an editor and contributor (for example).
Do you come across use cases where you need the additional level of indirection? Could you give an idea of where?
The typical admin request I see is "I have 43 teachers with 122 coming online next year". When they create a new user they need to easily add them to the core teacher role (group/whatever) and then add their own specific permissions (such as the ability to edit their own specific pages of content but not others). But often those lines can conflict or overlap as many teachers (and us really) wear many hats.
I have ended up checking a users permissions on an object basis, group basis, and site wide basis. Such that if the user belongs to group 'intern' which has publish=no, but has been specifically been given publish = yes to just one object then the specific permission has greater weight.
I tend to end up with both groups and roles.
I tend to think of groups as a logical grouping of people. For example, in a school you have teachers and students. Each would be a group.
I see roles as application level divisions, such as an admin, site editor, etc.
Now, whether or not these intersect for the purposes of security is another thing that I tend to go back and forth with. On the one hand, I have had success with having, say, a single editor role that is further refined (like a filter) based on the user's group (so a student who is an editor can edit student stuff, and a teacher who is an editor can edit teacher stuff)
I have also created unique roles for each - i.e. studentAdmin, teacherAdmin.
I think both work OK, but I have yet to come up with one consistent model that I am happy with.
My default approach was to have only positive permissions which solves the "which is more important" problem. Of course, if you have 20 objects and you want to be able to manage all expect one, then without negative permissions, you have to check 19 objects and then if you add a new object you'd have to add that to the permissions list and I can see the lack of negative permissions being an issue over time, so I guess I need to think about that some more. I love the simplicity of positive permissions only (with support for "all"), but get the limitations . . .
I get the idea of groups, I just don't feel I need it on the whole. I don't care whether you are a student or a teacher, only what things you want to and are allowed to do on the site. Thus I might have student and teacher roles, but if that doesn't intersect with the permissions, I might not make those distinctions at all. I'm spending a lot of time coming up with the absolutely simplest set of concepts required to meet my use cases, but it does take a lot of thinking about to figure this stuff out!
A filter could contain multiple AND or OR elements, although in practice I'd hope it wouldn't most of the time :-> That said, I don't usually HAVE such complex requirements so a more complex system may be appropriate for such use cases! Could you share some generlized examples of the sort of complex filters you come across?
I am starting to try and think in simpler terms as well and here is my offering... why can't groups and roles be the same thing (teams?) where groups are just roles with no permissions. So you could still use groups to identify multiple records to act upon (email all people in parents group) while logging in as a member of such a group gives you no functional access. And also use groups to assign permissions to other individuals.
I don't know if that makes any sense...
Interesting. I'll play with this a little more and blog on what works for me . . .
I think we can improve our system a good bit but like Peter, more in-depth analysis is necessary. Good stuff.
Thanks for the input! There is definitely a story to allowing extension of roles based permissions with user specific permissions and also for using variables so the permissions a role might have are based on a user specific property. Will keep playing with this and let you know what (if anything) I manage to come up with.
Happy Holidays.
I've posted the beginnings of a scenario at
http://www.aacr9.com/index/ali/security.txt
It is strictly the data layer only - all sql server 2000 code.
I had to come up with an example, so I create a table called tblURL and said:
"An administrator can Insert, Update, Delete and View the tblURL table".
"A member of the public can View the tblURL table".
Run it and tell me if I'm missing a layer of abstraction.