Multiple levels of authorization, not only role-based

aclauthorization

Our application uses multiple ways for authorizing access to a given resource. Although it's working, it's messy and… well, it doesn't seem right.

1) Role-based authorization

We have well defined roles where each role has access to a set of the resources and different roles can access the same resources.

Resources, as of now, are simply MVC actions mapped in a database table as module, controller and action.

This seems to be OK, but every time I need to add a new controller/action I have to map this resource to the database table.

2) User-based authorization

Besides role-based authorization, users can have more or less access to a subset of resources of another role. Eg.:

RoleA: resources a, b, c, d
RoleB: resources x, y, z
RoleC: resources 1, 2, 3
User1: has RoleA but needs to access resource y
User2: has RoleB and RoleC but does not have access to resource z

This is implemented as an user_resources table with entries for additional resources that the user has access or is denied (indicated by a flag).

I could create different roles with tailored access, treating roles as group of permissions, but that would lead to a roles explosion.

3) Model state authorization

If that's not enough, some actions can only be performed when the model is in a certain state (each model knows when something can be done). Eg.: an order can only be edited if the user has access to the edit resource (through steps #1 or #2) and the object Order can be edited.

Anoter example: an user can access a Customer if he has access to /customer/view resource and he owns that Customer (he is the contact info for that customer).

4) Display information in UI

A role, group of roles or individual users can see more or less information about a model, depending on it's state.

How can I simplify this authorization process without loosing flexibility in giving or restraining access to resources?

There is any pattern I'm missing here to unify all this authorization in a single place?

Best Answer

After a long time I finally found an answer that satisfies all my requirements: http://lostechies.com/derickbailey/2011/05/24/dont-do-role-based-authorization-checks-do-activity-based-checks/.

His solution is to consider everything as an activity, the permission to execute/call/whatever an activity is given to a role and users can have multiple roles.

What shines in this approach is that the permission check is done on the activity itself, not on the roles.

Related Topic