views:

208

answers:

3

We are currently designing a User Roles and Permissions System in our web application (ASP.NET), and it seems that we have several cases that do no fit within the classical Role-Based Access Control (RBAC). I will post several questions, each devoted to a particular case. This is my second question (the first question is here: http://stackoverflow.com/questions/2839797/non-rbac-user-roles-and-permissions-system-checking-the-users-city).

We have the following case: we need to implement a Manager role in our web application. However, a Manager can belong to one or several companies (within a big group of companies for which we are creating this web app). Say, there can be “Manager of companies A and B”, “Manager of company C”, etc.

Depending on the companies that the Manager belongs, he has access to certain operations: for example, he can communicate with clients only of those companies that he belongs to. That is, “Manager of companies A and B” can only have contacts with clients of companies A and B, and not with those of company C. He can also view clients’ details pages of companies A and B and not of C, etc.

It seems that this case falls within the RBAC. However, this is not really the case. We will need to create a ManagerRole class that will have a Companies property – that is, this will not be just a role as a collection of permissions (like in the classical RBAC), but a role with properties!

This was just one example of a role having properties. There will be others: for example, an Administrator role that will also belong to a number of companies and will also have other custom properties.

This means that we will a hierarchy or roles classes:


class Role – base class  
class ManagerRole : Role  
    List Companies  
class AdministratorRole : Role  
    List Companies  
    Other properties

We investigated pure RBAC and its implementation in several systems, and found no systems featuring a hierarchy or roles, each having custom properties. In RBAC, roles are just collections of permissions.

We could model our cases using permission with properties, like ManagerPermission, AdministratorPermission, but this has a lot of drawbacks, the main being that we will not be able to assign a role like “Manager of Companies A and B” to a user directly, but will have to create a role containing a ManagerPermission for companies A and B… Moreover, a "Manager" seems to be rather a "role" (position in the company) rather than a "permission" from the linguistic point of view.

Would be grateful for any ideas on this subject, as well as any experience in this field!

Thank you.

A: 

If you're problem would be solved by implementing inheritance for roles you could implement that.

Your example is another opportunity to go the attribute based access control way (eg allow a user that has the role of manager AND works for Company A). It is much harder to implement that a RBAC system though.

koen
+1  A: 

Let me first say that both of your questions are basically the same and should be consolidated . There is no value in multiple variations of the same concept.

You wish to add an extra level of arbitrary discrimination to the basic role.

To implement this sort of RBAC and retain the ability to take advantage of any of the inbuilt infrastructure you will need to make a few compromises and build a few custom implementations.

The first step is the compromise of adopting a role definition convention. e.g. when you want to determine if a user is in role 'manager' of 'companyA' you would define the rule, be it an attribute, code or perhaps a sitemaps, as 'manager-companyA' i.e. IsUserInRole("manager-companyA").

The second step is a custom RoleProvider implementation that can parse this and appropriately query your underlying data source maintaining the hierarchial relationships, for which you will have to provide a custom UI for maintenance.

You will need to, at a minimum, implement the methods used by ASP.Net to ensure that the roles are checked or output in the correct format.

IsUserInRole will get a string that you will have to, using convention, parse into constituent segments for verification, as described previously.

GetRolesForUser can be called when caching roles in cookies and must perform a hierarchial recursion of the roles and output all permutations. e.g. A user is manager for companyA and companyB so GetRolesForUser("user") should return an array consisting of the values manager-companyA and manager-companyB for use by the asp.net infrastructure that utilizes cached roles and does not interactively poll the RoleProvider.

This type of approach will provide you with the widest availability of established ASP.Net RBAC facilities while providing you with the customization you require.

So, to conclude, whenever you can adjust your expectations and/or redefine your requirements to work as much as possible with the existing infrastructure the less (MUCH LESS) code you must actually design, implement, test and maintain and the more time you have to spend concentrating on other aspects of your systems that do not already have an established infrastructure in place.

Sky Sanders
Code like IsUserInRole("manager-companyA") is not beautiful at all. We would like to have code like IsUserInRole("manager", companiesList). Moreover, the number of such properties of roles can be big, and strings like "manager-companyA,companyB..." can become too long.I think we could do better by creating our own permissions and roles system by ourselves, without using ASP.NET roles. I don't really see any trouble in this.
micha12
@micha - you may have misunderstood some of what I wrote. Perhaps a review might clear it up. And having designed, implemented, tested and maintained several custom provider stacks and regretting the wasted time, money and sleep, I can only wish you good luck.
Sky Sanders
@code poet. I could not agree more than fallacy of re-creating the wheel. However some times a wheel is not a good fit. A good book to read is ' Professional ASP.NET 2.0 Security, Membership, and Role Management' which describes in painful detail how every thing ticks.
ggonsalv
@ggonsalv. yes - if it just doesn't fit then it just doesn't fit. But if you can manipulate either the provided infrastructure or your requirements it is ALWAYS better to not be responsible for writing, testing and maintaining that type of code. My recommended reference material, which goes into even more painful detail, is Reflector and System.Web.Security, System.Web.Profile and System.COnfiguration and years of building custom provider stacks. ;-)
Sky Sanders
@codepoet- I was agreeing with you, either use the infrastructure, and squeeze the problem into infrastructure. Now unfortunately my coding experience has been mainly with .Net 1.1. However here is where new methods could make sense or not.Extension methods to the provider?? Overload IsInrole to take the role and paramlist. With security what is always confusing is there two sets of data to compare against. First roles the app is looking for and the roles the user possesses.Would a lambda expression make sense over here.... Just plain confused with all the new stuff
ggonsalv
@ggonsalv - at first blush and idea like extension methods may seem attractive, but the whole point of having an abstract factory pattern is to separate the implementation from the API. This is what enables the use of all of the built in plumbing and UI controls. Once you break that clear separation, it becomes a matter of degree to what built in functionality you are willing to sacrifice for the sake of customization. Extension methods really are not an answer as you are never dealing with the concrete class, you are dealing with a facade, e.g. Membership, ProfileManager, Roles are facades.
Sky Sanders
A: 

I'm not sure whether this might be what you are looking for or not but in my own search for information on RBAC systems I think I may have found something that suits your needs. I was reading an article by Tony Marston he talks about Virtual Private Database/ Row Level Security. These would give permissions at the data level meaning that you could restrict users to certain subsets of the information in your database. The links to the article is below.

http://www.tonymarston.net/php-mysql/role-based-access-control.html (Look in the "Other Types Of Access Control" section at the bottom of the page)

Again, I am not sure this is what you are looking for or not but it might be worth a quick browse.

Mike T