How do I re-use AuthorizationHandlers
to compose a composite requirement of the two handlers?
RequirementA
with one Handler IsAllowedAccessToA : AuthorizationHandler<RequirementA>
RequirementB
with one Handler IsAllowedAccessToB : AuthorizationHandler<RequirementB>
RequirementA_OR_B
where if it meets IsAllowedAccessToA
or IsAllowedAccessToB
it succeedsI have resources that are only accessible to RequirementA
and the same for RequirementB
. I also have resources that are available to A or B.
I can't figure out how to do this without duplicating IsAllowedAccessToA
and IsAllowedAccessToB
handlers
This article helps but is not exactly the same use case.
try this:
you're requirement class is like this:
public class PermissionRequirement : IAuthorizationRequirement
{
public PermissionRequirement(string permission)
{
this.Permission = permission;
}
public string Permission { get; }
}
and the handler should be like this:
public class PermissionAuthorizationHandler : AuthorizationHandler<PermissionRequirement>
{
private readonly IPermissionProvider _permissionProvider;
private readonly IUserProvider _userProvider;
public PermissionAuthorizationHandler(IPermissionProvider permissionProvider, IUserProvider userProvider)
{
// permissionProvider is a class that has a function called hasClaim, with bool return value that takes user id and claim as input arguments and realize weather the user id has access to the controller or not
this._permissionProvider = permissionProvider;
// userProvider, return the id of current user
this._userProvider = userProvider;
}
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
{
var hasClaim= await this._permissionProvider.HasClaim(this._userProvider.GetUserId(), requirement.Permission)
.ConfigureAwait(false);
if (hasClaim) context.Succeed(requirement);
else
context.Fail();
}
}
There isn't a super clean way to express a policy as either of two other policies.
But you could write this imperatively as a helper method that authorizes against both policies, you wouldn't be able to do this via Authorize, but you could just call this where needed:
async Task<bool> IsAllowedAccessToAOrB(ClaimsPrincipal user, IAuthorizationService auth, object resource) {
return await auth.AuthorizeAsync(user, resource, "PolicyA") || await auth.AuthorizeAsync(user, resource, "PolicyB")
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With