0

I am trying to figure out what is the best way to create custom authorization attribute for my asp.net core application. I have seen this post and I am aware of the 2 approaches discussed here. How do you create a custom AuthorizeAttribute in ASP.NET Core?

1) Using IAuthorizationFilter

2) Using Policies

I saw that the official document suggests that we should be using policies and not IAuthorizationFilter but I felt that using policies for my scenario is an overkill. I personally liked IAuthorizationFilter approach more.

I have a very basic requirement. I want to create an authorize attribute for my web api and need to throw 403 if the current user is not whitelisted to use this API. I really don't care about the scopes(canRead, canWrite, can readWrite etc). If I go ahead with policy approach, I may be using the same policy for all my APIs. What is the best way to achieve this?

Lukas
  • 549
  • 1
  • 4
  • 16
user911
  • 1,269
  • 5
  • 20
  • 41

1 Answers1

2

Using policies for something like this isn't overkill. You need a requirement:

public class WhitelistRequirement: IAuthorizationRequirement
{
}

A handler:

public class WhitelistHandler : AuthorizationHandler<WhitelistRequirement>
{

    // Implement a constructor to inject dependencies, such as your whitelist

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
                                                   WhitelistRequirement requirement)
    {
        if (isInWhitelist) // Your implementation here
        {
            context.Succeed(requirement);
        }

        return Task.CompletedTask;
    }
}

Register both in ConfigureServices:

services.AddAuthorization(options =>
            options.AddPolicy("WhitelistPolicy",
            b => b.AddRequirements(new WhitelistRequirement())));

services.AddSingleton<IAuthorizationHandler, WhitelistHandler>();

Then use your policy:

[Authorize(Policy = "WhitelistPolicy")]

You can apply the policy globally with a global filter:

services.AddMvc(config =>
{
    var policy = new AuthorizationPolicyBuilder()
                     .AddRequirements(new WhitelistRequirement())
                     .Build();
    config.Filters.Add(new AuthorizeFilter(policy));
})

The resulting behavior for unauthenticated or forbidden users depends on the implementation of the "challenge" and "forbid" behaviors in your app's authentication handler.

See here.

nlawalker
  • 5,654
  • 6
  • 26
  • 43
  • Same as with a controller or anything else - create a constructor that receives any needed dependencies, then make sure those dependencies are registered. https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.2 – nlawalker May 29 '19 at 23:55
  • still isn't this too much work when compared to custom Authorization attribute? (eg. with custom Authorization attribute there is no bootstrapping in `Startup.cs`) Is there a specific downside of using custom Authorization attribute when compared over Authorization Policy + Requirement + Handler implementation? Sure, policy based authorization provides great extendability in terns of being able to have multiple Handlers for one Requirement etc. but.. is there a drawback in using custom Authorization attribute when a given authorization need is quite rudimentary? – dan Nov 20 '20 at 18:17