Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I am writing an enterprise web-forms-frontend application for in-house use. It has Direct access control (DAC) masquerading as Role-based access control (RBAC).

For anonymization purposes, let's call the main unit of information stored in my application a Document, and the roles in the company a Boss, a Grunt and a C-level executive. There are also Externals (e.g. somebody working for a business partner of ours). The general guideline is that everybody but externals should be able to read all documents, C-level execs can write everything, Bosses can write the Documents belonging to their own department, and Grunts can only write Documents personally assigned to them. Fairly standard thus far.

But what users actually want is that they can make arbitrary exceptions to the above. They want that any person in the system can be granted write access to any Document, and that Externals can be granted Read access to any document. (Actually, it is more complicated than that, with more roles and finer granularity of permissions, including management of who can propagate which permission to others, but the above description illustrates the core of the problem well enough). So what I have is basically permissions on a personal level, and the roles are only a convenient way of having default settings for the personal-level permissions when a user or a Document is added to the system, instead of having somebody fill out a whole row or column in an access control matrix by hand.

Now I have already designed a Permissions table in my database, which has a User FK, Document FK and columns for the different types of permissions. What I am not sure is what I should save in the table.

  • Alternative 1: I save all permissions in this table (pure DAC) and have the logic tier mimic a RBAC. E.g. when a new Boss is added, a row for each Document in the system is added to the DB, with Read permissions for all documents and Write for the Documents of her department.
  • Alternative 2: I save the deviations from the role guidelines only. So when a new Boss is added, nothing is written to the permissions table. But when an executive gives a Boss the rights to write to a Document from a different department, then a single row is added to reflect that information.

I am not sure which alternative would be better. The first one feels closer to textbook implementation, and if a principle has made it into a textbook, then there is normally good reason to use it. But in my case, it also hurts the DRY principle - after all, if the information that a C-level exec can write to Document X is derivable from his role, writing a row with this information in the DB is redundant.

What are the advantages and disadvantages of each approach in terms of a) application performance and b) complexity of implementation? What headaches can I expect from each?

Keep in mind that 1) I don't plan to implement a full logic tier. The whole application is practically a convenient CRUD frontend to a database, so I will be doing DB queries for each page view instead of keeping a collection of Document objects in memory. (I know the advantages of a MVC pattern, but it was decided that it will be overkill for this project). 2) I am programming this in ASP .NET 4.5, so the closer I stay to roles, the more I can let the framework do the heavy lifting for me. 3) I have thought of implementing groups orthogonal to the roles to manage access, but it doesn't make sense in my case.

share|improve this question
    
I would like to know why the question was downvoted, please. –  Rumi P. Jan 21 '13 at 9:42
    
Did you mean discretionary access control (DAC)? –  David Brossard May 6 at 14:16
add comment

2 Answers

User permissions

If you had full permissions information for each user entry in your database, you'd have the advantage of simplicity. You want to know the permissions of user X, load permissions for user X. The advantage is in the work you'd have to do. It's also true that it would use more database space, but I consider that a minor disadvantage that isn't really worth mentioning.

If your client was happy micromanaging the permissions of each individual user, this is ideal. You yourself do not have to manage the permissions, and at the same time, you allow full control to your client.

The problem comes in when the client starts complaining about having too many users to change. The sensible solution at this point is to give users group permissions, but modifying your current model in order to allow for groups is somewhat of a nightmare. Not to mention that updating the permissions of a group means batch updating all users with that group. It quickly becomes unmanageable and there is no easy way to switch permissions model.

Role permissions

I would advise you to use a role-based system. Instead of holding all permissions for every user, have a user record point to a permissions group or NULL. If it is NULL, have a default (undeletable) permission group that a user will inherit from if none is specified. Clients modify a permission group directly (including the default permissions group) or the permission group that a user points to, but they remain separate entities. In this way, they have all the individual control they had before, creating permission groups for single users if they desire it, but they can also make blanket permissions and simply assign users to it.

You could argue that it is slower to load, but if you make a point to cache permissions, it will only be slow in the first load. The only true disadvantage to this approach is that it is a little trickier to implement with respect to the first approach, but considering the headaches you'd have trying to implement the second approach after already having used the first approach makes it worthwhile in my humble opinion.

share|improve this answer
    
+1 for the good description of the standard cases. But I am aware of them, and this is not what I need. My users require the flexibility micromanagement would give them, but insist that my software does the micromanagement for them in all the default cases. What I am wondering is how to implement the "handling of default cases" part - by accepting extra complexity in my .NET code, or my accepting extra complexity in my DB structure and SQL queries. –  Rumi P. Jan 21 '13 at 9:40
    
@RumiP. If all permission information is stored in the database, how will you know what is "default" and what the user explicitly inserted? That would require additional columns as well as additional code, and in my humble opinion, it isn't worth your time to mess with that. You can easily convert from a flexible software code to a database-heavy approach. Not so easy to do the opposite. –  Neil Jan 21 '13 at 11:14
add comment

You should not implement your own authorization model but rather use existing ones e.g. an RBAC implementation, claims-based access control, or attribute-based access control (ABAC).

With respect to ABAC, there is an authorization standard that exists which you can use to define your authorization policies. This standard is called XACML, the eXtensible Access Control Markup Language. You can read up on both topics here:

XACML defines an architecture with the notion of:

  • a policy decision point (PDP),
  • a policy enforcement point (PEP), and
  • a policy information point (PIP).

In the typical flow, the PEP protects your data / service / API. The PEP would send an authorization request to the PDP:

  • Can user Alice view record #123?

The PDP would turn to the PIP to retrieve missing attributes e.g. the user's role and clearance as well as resource attributes e.g. the sensitivity of data, a whitelist or blacklist... Based on the new information, the PDP can reach a decision: Permit or Deny. Access is allowed or blocked.

With XACML there is no limit to the richness of the authorization policies. I work for a company, Axiomatics, that implements XACML, and our solutions are used in manufacturing, healthcare, banking to secure access to sensitive data in a dynamic way (e.g. managers can edit documents that they own).

XACML enables externalized authorization that is managed centrally. It also enables what I like to call any-depth authorization meaning that you can apply XACML to web APIs, business logic, presentation UIs, as well as databases.

HTH

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.