Paul
Paul

Reputation: 705

declarative resource based requirement authorization not working with API Controller

I am trying setup an authoriztion policy that I can use to decorate actions in API Controllers in .net core 3.1. I have been following these examples : https://learn.microsoft.com/en-us/aspnet/core/security/authorization/resourcebased?view=aspnetcore-3.1

If i have an API action decorated like below my code does not hit the handlerequirementAsync method of the handler and I get a 403 Forbidden response from swagger. If i remove the document model from the handler/requirement it does work. Am I doing something wrong or is this not supported for api requests?

here is the other relevant code :

    public class DocumentAuthorizationHandler : 
    AuthorizationHandler<SameAuthorRequirement, Document>
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
                                                   SameAuthorRequirement requirement,
                                                   Document resource)
    {
        if (context.User.Identity?.Name == resource.Author)
        {
            context.Succeed(requirement);
        }

        return Task.CompletedTask;
    }
}

public class SameAuthorRequirement : IAuthorizationRequirement { }


[Authorize(Policy = "EditPolicy")]
public async Task<FileResult> RetreiveFile([FromRoute]Document model)


 {
 }

services.AddAuthorization(options =>
{
    options.AddPolicy("EditPolicy", policy =>
        policy.Requirements.Add(new SameAuthorRequirement()));
});

services.AddSingleton<IAuthorizationHandler, DocumentAuthorizationHandler>();

Upvotes: 0

Views: 160

Answers (1)

Ajeet Kumar
Ajeet Kumar

Reputation: 729

You should have to inject IAuthorizationService in the controller constructor

public class AbcController : Controller
{
   private readonly IAuthorizationService _authorizationService;

   public AbcController(IAuthorizationService authorizationService)
   {
      _authorizationService = authorizationService;
   } 
   // No need to add this [Authorize(Policy = "EditPolicy")]
   public async Task<FileResult> RetreiveFile([FromRoute]Document model)
   {
      //add this below line which shall call the handler
       var authorizationResult = await _authorizationService.AuthorizeAsync(User, model, "EditPolicy"); 
   }

Upvotes: 0

Related Questions