title: Role Based Authorization with an Extra Twist
body: <p>I'm looking to solve a problem I have with implementing role-based authorization of a project I'm working on.  The project is in ASP.NET MVC 3.</p>
  
  <p>The application authenticates users and these users have certain system-wide roles associated with them.  This part I am fine with.</p>
  
  <p>The problem arises with the concept of Projects, Teams and Team Roles within the application.  For each Project that a manager creates, they can create a Team.  This Team consists of other system users, who will assume Roles within the Team, but just for that Project.</p>
  
  <p>So a user may have Role A in one project and may have Role B in another and Role C in another.</p>
  
  <p>The biggest problem I face, is that at the moment the Action Method might have the signature (example code, not real code):</p>
  
  <pre><code>[Authorize(Roles = "SomeExampleSystemRole")]
  public ActionResult DoSomeTask(Guid id)
  {
      // id is the project id.
  }
  </code></pre>
  
  <p>In which case even if I coded up a custom attribute, I wouldn't know which Project (and subsequently which Team) the user was calling this task in relation to, not until I was inside the method and could access the 'id' argument.</p>
  
  <p>So far I have thought of creating another class, but this still would have to sit within the Action Method, so that it knows the current Project id:</p>
  
  <pre><code>[Authorize(Roles = "SomeExampleSystemRole")]
  public ActionResult DoSomeTask(Guid id)
  {
      // some code to get the current user identity.
  
      // id is the project id.
      TeamAuthorization auth = new TeamAuthorization(userIdentity, id);
  
      bool authPassed = auth.DoesUserHaveTeamRole("RoleC");
  }
  </code></pre>
  
  <p>However if the user doesn't have the system role that's required, they'll never get to the secondary authorization code inside the Action Method.</p>
  
  <p>Does anyone have any ideas on how this sort of transient role problem can be elegantly solved?  In addition, we're moving away from a heavily 'Session' based implementation and don't envisage a 'Session' based solution as being manageable.</p>
  
  <p>I'm currently looking at whether the Team Roles are different from the System Roles, if so then the solution above may work in part.</p>
  
  <p>Would it be possible using Attributes to be able to read the 'id' in the method's parameters?</p>
  
  <p>Any suggestions would be greatly appreciated.  Many thanks.</p>
  
  <p>Edit:</p>
  
  <p>I've had an extra thought that it might be best to simply apply a global <code>Authorize</code> attribute to ensure that users are authenticated, then role-up the system roles into the <code>TeamAuthorization</code> class, so that at least system and team roles can be joined into one super-set.  This also might work in instances where the project or team id isn't passed into the method (or as obvious).</p>