views:

139

answers:

3

There are plenty of questions (and information) on setting up asp.net membership, role providers and the like. Whether or not you should use the built in platform provided by microsoft, or role extend the base classes and role your own.

I have decided to extend the default providers and implement my own membership and role providers. Now my question, is specifically around role authentication.

Traditionally, you would create roles maybe like 'Manager, Administrator, Employee, Super User' or whatever you have. But what would/should you do with respect to permissions which I consider to be a finer grain of control? Let me elaborate....

Within my asp.net mvc site I have different areas like administration, management, messaging, reporting etc. I would crate roles for each of these like 'Administrator', 'Manager', 'Reporter' etc. Without the appropriate role, you can't gain access to that area of the site. So I would lock down the entire controllers with this at the class level.

But now take one area as an example; messaging, and say I wanted to have finer grain permissions for CRUD; create a message, view/read messages, edit messages, delete messages etc.

Finally my question. How would it be best to implement this finer grain of control? One approach I see (not sure if it is a good one), is to just create asp.net membership roles for everything. So I might have....

Messenger (broad level role), CreateMessage, ReadMessage, EditMessage, DeleteMessage.

On one hand I would like some users to be able to read/view messages. But not necessarily create or delete them. Individual controller actions could have the specific roles applied.

Do you see any problems with this approach? Do you have a better idea?

Solution So Far

I have decided to create my own schema and implement custom membership and role providers. My schema includes;

  • User
  • UserProfile
  • Permission
  • PermissionAssignment
  • Role
  • RoleAssignment

Going to be away for the next day or two but will update with more information when I get a chance.

A: 

As well as adding [Authorize(Roles="Administrator")] etc above your controller. You can also put that attribute on the indiviual Actions too

BritishDeveloper
I did actually mention this in my question."...Individual controller actions could have the specific roles applied."
Joshua Hayes
+2  A: 

With respect to your CRUD example, aren't you really talking about authorization, and would the authorization vary between the membership roles "Manager" and "Reporter"? I think you need to create a separate mechanism for those finer grained activities if the roles do not distinguish between a read and write authorization between messages.

If you were to create a role for each action - EditMessage, DeleteMessage - what will you do in the case when Manager A should NOT be able to delete messages for Manager B?

David Robbins
Hi David,Thanks for your input."I think you need to create a separate mechanism for those finer grained activities if the roles do not distinguish between a read and write authorization between messages."Well this is exactly what I'm wondering.As for your scenario...not sure. Good point though. I don't *think* that will be an issue. I'm mainly thinking that a higher level manager will have full access to an area of the site, whilst they might give partial access (read only?) to an employee under them etc.Compared to general roles, I haven't seen permissions discussed much.
Joshua Hayes
I ran into the same scenario last year on a project where I had roles such as AgentManager and Agent, yet the authorization rule that only Agent David Robbins could see David Robbins records, while and AgentManager can see only her direct reports.I solved the issue with a few tables in SQL to represent the relationships between Agents and AgentManagers and their respective records.
David Robbins
+2  A: 

I think you should forget about roles on the authorization mechanism, ask for permissions instead (at the end a role is an agrupation of permissions), so if you look it that way, your Authorize Attribute should ask for an entity and action, not for a particular role. Something like:

[Authorize(Entities.Message, Actions.Create)]
public ActionResult CreateMessage()

[Authorize(Entities.Message, Actions.Edit)]
public ActionResult EditMessage()

[Authorize(Entities.Message, Actions.View)]
public ActionResult ViewMessage()

That way your roles do what they do best, abstract permissions collection instead of determining a inflexible way of access level.

EDIT: To handle specific rules like the one pointed by David Robbins, Manager A is not allowed to delete messages created by Manager B, assuming they both have the required permission to access this Controller Action, the Authorize is not responsible to check this type of rules, and even if you try to check that at Action Filter level it will be a pain, so what you can do is extend the Authorize validation to the ActionResult (injecting an action parameter holding the validation result), and let the ActionResult make the logic decision there with all the arguments in place.

This is a similar question, is not exactly the case pointed out here, but its a good starting point on extending the Authorize validation with Action Parameters.

Omar
Is it possible to take that a bit further and say not only "is this action allowed?" but to say "is this action allowed on this particular entity?" e.g. the situation David Robbins points out where Manager A is not allowed to delete messages created by Manager B?
Iain Galloway
that particular scenario can be handle by the Action but the actual logic of the Authorize and the ActionResult will change a bit, a previous related queston show how you can archive that,http://stackoverflow.com/questions/2872588/asp-net-mvc-authorization-permission-to-use-model-classes/2878159#2878159
Omar
Thanks Omar, I have been doing a bit more work on this and will update when with some more information on where I am at with. Cheers.
Joshua Hayes
I am currently using both roles and permissions but I think will ultimately move to your idea of using roles as an aggregation of permissions and just work predominantly with permissions.As I have come around to your suggestion, I have marked your answer as correct. Cheers.
Joshua Hayes