In a .Net core Webapi 2.1
project, I have a tons of action methods.
All action methods should be authorized against the same policy (named FooPolicy
) but with a different required argument.
Based on Microsoft's docs: Policy-based-Authorization
One way would be to declare a tons of policies based on different input argument:
services.AddAuthorization(options =>
{
options.AddPolicy("FooPolicy1", policy =>policy.Requirements.Add(new FooRequirement(1)));
options.AddPolicy("FooPolicy2", policy =>policy.Requirements.Add(new FooRequirement(2)));
options.AddPolicy("FooPolicy3", policy =>policy.Requirements.Add(new FooRequirement(3)));
//... May be 30 more same policies here ...
});
As i earlier mentioned, only different part is in new FooRequirement(diffArgs)
. The other challenge for this solution would be to add each FooPolicy
on it's corresponding action method and you may miss a couple of theme:
[Authorize(Policy = "FooPolicy1")]
public IActionResult ActionMethodFoo1(...) {...}
[Authorize(Policy = "FooPolicy2")]
public IActionResult ActionMethodFoo2(...) {...}
[Authorize(Policy = "FooPolicy3")]
public IActionResult ActionMethodFoo3(...) {...}
...List still goes on...
Is there any solution like: declare a policy once but use it with different instance of FooRequirement
(which is of type IAuthorizationHandler
)? like so:
services.AddAuthorization(options =>
{
options.AddPolicy("FooPolicy", policy =>policy.Requirements.Add(?));
});
And on the action methods:
[Authorize(Policy = "FooPolicy", required = new FooRequirement(1))]
public IActionResult ActionMethodFoo1(...) {...}
[Authorize(Policy = "FooPolicy", required = new FooRequirement(2))]
public IActionResult ActionMethodFoo2(...) {...}
[Authorize(Policy = "FooPolicy", required = new FooRequirement(3))]
public IActionResult ActionMethodFoo3(...) {...}
The main idea is to declare policy once. Two recent code blocks are psudo-code, Does any body knows practical solution with similar concept?
You could implement your own IAuthorizationFilter
custom IAuthorizationFilter
public class CustomAuthorize : IAuthorizationFilter
{
private readonly int _input;
public CustomAuthorize(int input)
{
_input = input;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
//custom validation rule
if (_input == 1)
{
context.Result = new ForbidResult();
}
}
}
Custom CustomAuthorizeAttribute
public class CustomAuthorizeAttribute : TypeFilterAttribute
{
public CustomAuthorizeAttribute(int input) : base(typeof(CustomAuthorize))
{
Arguments = new object[] { input };
}
}
Use
[CustomAuthorizeAttribute(1)]
public IActionResult About()