How to Extend/Architect the ASP.NET MVC 3 Authorize Attribute to Handle This Scenario

Mastro picture Mastro · Feb 26, 2011 · Viewed 7.3k times · Source

I've been trying to think this answer through and can't find a good solution on how to properly do this.

I've read over these articles:
http://schotime.net/blog/index.php/2009/02/17/custom-authorization-with-aspnet-mvc/
http://geekswithblogs.net/brians/archive/2010/07/08/implementing-a-custom-asp.net-mvc-authorization-filter.aspx
ASP.NET MVC custom authorization
http://davidhayden.com/blog/dave/archive/2009/04/09/CustomAuthorizationASPNETMVCFrameworkAuthorizeAttribute.aspx
Custom Authorize Attribute additional Param?

Thinking maybe the last one is close.


Scenario:

  • User's create Roles
  • User's can assign what the Role has access to do.
  • User's add users to those Roles
  • User's are also part of a Department.

So in the controller how could I say that a user has access to an action, since I don't know what are the Roles the User's Admin created?

So in logic... let's say I have a Task controller with a "Create", "Details". The Task has a Department of "Clothing".

  • Task:
    -- TaskID
    -- TaskTitle
    -- TaskDepartmentID

  • -- User:
    -- UserName
    -- Roles
    -- Departments

    I would somehow associate the "Create" action with "Create Task" ability
    I would somehow associate the "Details" action with "View Task Details" ability

The admin would add a new role called "Task Users" and say this role can "Create Tasks"
The admin would also allow this role to "View Task Details"
The admin would turn on "Department Level Security"


Creating:
When the Task Create is called on the controller I would need to make sure the user is in a Role that allows "Create Task". So by default I can't send in the "Roles" allowed into the Authorize Attribute because I don't know them. I somehow need to send in all the Roles the user has and see if a role has access to "Create Tasks"

Viewing with Department Security:
When another user goes to view this task, they may have access to "View Task Details" (which I can figure out however I solve the first issue). However, since the Task is for another department other then the one they are in, I need to deny access. The user can only "View Task Details" if the Task is part of one of the Department the User is in.

This is what I can't figure out. How to properly extend the AuthorizeAttribute so I can send in a list of Roles via GerRolesForUser since it only accepts a string, and how to identify what Action it's for and then limit security on another level by checking for the Department ID.

Department ID doesn't necessarily have to be cached so maybe I can do that at the controller level.

Answer

Pradeep picture Pradeep · Feb 26, 2011

I had somewhat similar problem and I did not use Authorize attribute.

Instead I decided to extend Controller class and override the implementation of OnActionExecuting. In my implementation then I could perform all checks like to which department user belonged and whether he is good enough to see the data of other departments. See if this approach works for you.