Let's say that you have a .net web api with a GetResource(int resourceId) action. This action (with the specified id) should only be authorized for a user associated with that id (the resource could for instance be a blogpost written by the user).
This could be solved in many ways, but an example is given below.
public Resource GetResource(int id)
{
string name = Thread.CurrentPrincipal.Identity.Name;
var user = userRepository.SingleOrDefault(x => x.UserName == name);
var resource = resourceRepository.Find(id);
if (resource.UserId != user.UserId)
{
throw new HttpResponseException(HttpStatusCode.Unauthorized);
}
return resource;
}
where the user has been authenticated by some sort of mechanicm.
Now, let's say that I also want a user of, for instance, an admin type, to be authorized to consume the endpoint (with the same id). This user does not have any direct relation to the resource but does have authorization because of it's type (or role). This could be solved by just checking if the user is of admin type and the return the resource.
Is there any way to centralize this in a way so that I don't have to write authorization code in every action?
Edit Based on the answers I think I have to clarify my question.
What I am really after is some mechanism that makes it possible to have resource based authorization, but at the same time allow some users to also consume the same endpoint and the same resource. The action below would solve this for this specific endpoint and for this specific Role (Admin).
public Resource GetResource(int id)
{
string name = Thread.CurrentPrincipal.Identity.Name;
var user = userRepository.SingleOrDefault(x => x.UserName == name);
var resource = resourceRepository.Find(id);
if (!user.Roles.Any(x => x.RoleName == "Admin" || resource.UserId != user.UserId)
{
throw new HttpResponseException(HttpStatusCode.Unauthorized);
}
return resource;
}
The thing I am after is some generic way to solve this problem so that I don't have to write two different endpoints with the same purpose or write resource specific code in every endpoint.