I think you may be getting authorization and permissions confused. "Dynamic authorization" isn't something you ever do.
Authorization is the act of verifying an author.
- Request claims it is being sent from Alice.
- Request presents a password or authorization token that proves the requester is Alice.
- Server verifies that the password or authorization token matches its records for Alice.
Permissions are the business logic that specifies who can do what in your system.
- Request is already authorized, and we know it came from Alice.
- Alice is requesting to delete an important resource.
- Is Alice an administrator? If not, tell her she can't do that because she doesn't have permission. (403 Forbidden)
The built-in [Authorize]
attribute lets you optionally specify Roles
that are permitted to access a resource. That option to specify permissions as part of authorization is slightly misplaced, in my opinion.
My advice would be to leave authorization as purely the process of verifying the author of a request. The BasicAuthHttpModule
described here is close to what you want already.
Non-trivial permissions logic needs to be handled inside of your action body. Here's an example:
//Some authorization logic:
// Only let a request enter this action if the author of
// the request has been verified
[Authorize]
[HttpDelete]
[Route("resource/{id}")]
public IHttpActionResult Delete(Guid id)
{
var resourceOwner = GetResourceOwner(id);
//Some permissions logic:
// Only allow deletion of the resource if the
// user is both an admin and the owner.
if (!User.IsInRole("admin") || User.Identity.Name != resourceOwner)
{
return StatusCode(HttpStatusCode.Forbidden);
}
DeleteResource(id);
return StatusCode(HttpStatusCode.NoContent);
}
In this example, it would be difficult to convey the permissions logic as an attribute on the action, because the portion of the permissions that compares the current user to the resource owner can only be evaluated after you have actually gotten the resource owner info from your backend storage device.