Reputation: 77
I have a controller with some utility methods that I use in many internal projects. Until now I've always copied the source file in every project. Now I want to create a NuGet package for this controller to use in internal repository.
The problem is with the authorization for this controller. I don't want to put a specific [Authorize()]
attribute on the controller class (or its actions) because the authorization should be chosen by the developer which use the package: in some project the controller can be used by everyone, in some project can be used only by authenticated users, in others can be used with a custom policy.
Any ideas on how to achieve the purpose?
Upvotes: 2
Views: 2428
Reputation: 14472
I'd add the Authorize
attribute with a forced policy, that all your users must implement. Something like this:
[Authorise(Policy = "MyLibPolicy")]
public class LibController : Controller
{
}
Then, based on their needs, they can declare it differently in their Configure
method:
If they need authenticated users:
services.AddAuthorization(options =>
{
options.AddPolicy("MyLibPolicy", policy =>
{
policy.RequireAuthenticatedUser();
});
});
If they need a custom policy:
services.AddAuthorization(options =>
{
options.AddPolicy("MyLibPolicy", policy =>
{
policy.RequireAuthenticatedUser();
policy.RequireRole("SomeRole");
// other requirements
});
});
If they want anonymous access:
Now, that's the tricky part, because you can't create an empty policy (a policy requires at least one requirement).
You can, however, create your own custom requirement (in your Nuget package) to allow anonymous users (basically, a requirement that always succeed).
public class AllowAnonymousAuthorizationRequirement : AuthorizationHandler<IAuthorizationRequirement>, IAuthorizationRequirement
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, IAuthorizationRequirement requirement)
{
context.Succeed(requirement);
return Task.CompletedTask;
}
}
Then, your users will need to register it before using it, like this:
services.AddScoped<IAuthorizationHandler, AllowAnonymousAuthorizationRequirement>();
services.AddAuthorization(options =>
{
options.AddPolicy("MyLibPolicy", policy =>
{
policy.AddRequirements(new AllowAnonymousAuthorizationRequirement());
});
});
Upvotes: 8