When it comes to implementing an Authorization Engine or
Permission Engine for an ASP.Net Core Web API, we can use the Identity
Framework. Please refer my previous post
on Claim
based Authorization in Asp.Net Core.
If you have a basic understanding on how claim based
authorization works, you should be already familiar with security policies.
Security Policies are used to decorate controller action to control authorization,
and the policy defines what is required to satisfy the policy. Usually a Policy
check if the logged in user has certain claims (one or multiple) with him.
Normally one or few claims required to satisfy a policy and most of the time it
is one claim per policy.
If your authorization engine is mainly based on one claim
per policy (or if you can model it in such away), you will notice that you will
have to write large amount of security policies where each policy is checking
whether the user has a certain claim. This is a repetitive and annoying task
which you would have to spend considerable amount of time.
What if Possible to Decorate Controller Actions with Claim Itself?
That’s sounds nice. Instead of writing hundreds of security
policies, just decorate the actions with the claim that required to access it.
But unfortunately it is not supported by Identity Framework by default. It only
allows to specify the policy names or the role names.
Is There a Workaround?
Yes! Identity framework supports creating dynamic policies
by implementing IAuthorizationPolicyProvider
and AuthorizeAttribute
Custom Authorize Attribute
internal class ClaimAuthorizeAttribute : AuthorizeAttribute
{
const string POLICY_PREFIX = "REQUIRE_CLAIM_";
public ClaimAuthorizeAttribute(string claim) => Claim = claim;
public string Claim
{
get
{
var claim = Policy.Substring(POLICY_PREFIX.Length);
return claim;
}
set
{
Policy = $"{POLICY_PREFIX}{value}";
}
}
}
Custom Authorization Policy Provider
internal class CustomAuthorizationPolicyProvider : IAuthorizationPolicyProvider
{
const string POLICY_PREFIX = "REQUIRE_CLAIM_";
public Task GetDefaultPolicyAsync()
{
return
Task.FromResult(new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser().Build());
}
public
Task GetPolicyAsync( string policyName)
{
var requiredClaim =
policyName.Substring(POLICY_PREFIX.Length);
var policy = new AuthorizationPolicyBuilder();
policy.RequireClaim(CustomClaimTypes.Permission, requiredClaim);
return
Task.FromResult(policy.Build());
}
}
Tell .Net Core to Use Our Custom Policy Provider Instead the Default One
In the startup.cs add the following line in
ConfigureServices() Method.
services.AddSingleton();
Decorating Controller Action with the New Attribute
[ClaimAuthorize(“DRIVER_VIEW”)]
public async Task GetAsync( string id)
{
var result = await
_driverService.GetDriverWithPostCodesAsync(id);
return result;
}
Summary
Using this approach you can simply outsource the burden of
creating hundreds of authorization policies. Eventually that will save large
amount of development time of your team. Also the code will be nice and clean.
No comments:
Post a Comment