I want to add authorization to my .NET Core API. Lets say I have a PersonController with the following actions:
GetPerson (retrieves a Person based on id)
PostPerson (adds a new Person)
DeletePerson (Deletes a Person)
[Route("[controller]")] [ApiController] public class PersonController : ControllerBase { [HttpGet("{id}")] public async Task<ActionResult<PersonModel>> GetPerson(int id) { // } [HttpPost] public async Task<ActionResult<PersonModel>> PostPerson(PersonModel model) { // } [HttpDelete("{id}")] public async Task<ActionResult> DeletePerson(int id) { // } }
For this example I will use two roles. 'SuperAdmin' which should be able to do all actions and 'PersonReader' which should only be able to do the GetPerson call. Trying to do PostPerson or DeletePerson as a PersonReader should fail.
I created the following authorization policies:
options.AddPolicy("SuperAdmin", policy =>
policy.RequireAuthenticatedUser()
.RequireRole("SuperAdmin")
);
options.AddPolicy("PersonReader", policy =>
policy.RequireAuthenticatedUser()
.RequireRole("PersonReader")
);
But now I want to bind these policies to the controller actions, to say what policies are required to be able to do the controller actions. I know this can be done with an authorizationAttribute like this: [Authorize(Policy="X"]
But I want to be able to do this without using AuthorizationAttributes.
Why can I not use [Authorize] attributes?
I won't go in too much detail, but the source code of the Controller is generated. This means all manual changes will be overwritten once it is generated again. Because of this the authorization should not be in the controller.
In the startup.cs I map the controllers to endpoints like this:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
It is possible to bind one policy for all controllers like this:
endpoints.MapControllers().RequireAuthorization("SuperAdmin");
But this means I will require the 'SuperAdmin' policy for all controller actions. With this I cannot define required policies for a specific action. I was hoping to do something like this:
// pseudo-code
// endpoints.MapControllerAction("GetPerson").RequireAuthorization("SuperAdmin", "PersonReader");
Unfortunately I cannot find any way of doing this. Is there a way to bind policies to controller actions without using the [Authorize] attribute?