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?