Why create a custom authorization policy
Let's say we want to create a policy with multiple requirements. For example to be able to edit a given role, the following are the requirements.
However, this would not meet our authorization requirement. For this policy to succeed, all the requirements in the policy must be satisfied i.e there is an AND condition between all the requirements. In our case, we want an AND condition between the first and second requirement and an OR condition between the first 2 requirements and the last requirement.
In simple terms to be able to edit a given role, the logged-in user must be
Member of the Admin role AND have Edit Role claim with a value of true
OR
Member of the Super Admin role
Using a Func to create a custom policy
We can use a func to create a custom policy that meets our authorization need. If you are new to func, we discussed them in detail in Part 100 of C# tutorial.
Let's say we want to create a policy with multiple requirements. For example to be able to edit a given role, the following are the requirements.
- Must be a member of the Admin role AND
- Must have Edit Role claim with a value of true OR
- Must be a member of the Super Admin role
AuthorizationPolicyBuilder supports fluent syntax, so we could chain multiple calls to RequireClaim and RequireRole methods as shown below.
services.AddAuthorization(options =>
{
options.AddPolicy("EditRolePolicy", policy => policy
.RequireRole("Admin")
.RequireClaim("Edit Role", "true")
.RequireRole("Super Admin")
);
});
{
options.AddPolicy("EditRolePolicy", policy => policy
.RequireRole("Admin")
.RequireClaim("Edit Role", "true")
.RequireRole("Super Admin")
);
});
However, this would not meet our authorization requirement. For this policy to succeed, all the requirements in the policy must be satisfied i.e there is an AND condition between all the requirements. In our case, we want an AND condition between the first and second requirement and an OR condition between the first 2 requirements and the last requirement.
In simple terms to be able to edit a given role, the logged-in user must be
Member of the Admin role AND have Edit Role claim with a value of true
OR
Member of the Super Admin role
Using a Func to create a custom policy
We can use a func to create a custom policy that meets our authorization need. If you are new to func, we discussed them in detail in Part 100 of C# tutorial.
services.AddAuthorization(options =>
{
options.AddPolicy("EditRolePolicy", policy => policy.RequireAssertion(context =>
context.User.IsInRole("Admin") &&
context.User.HasClaim(claim => claim.Type == "Edit Role" && claim.Value == "true") ||
context.User.IsInRole("Super Admin")
));
});
{
options.AddPolicy("EditRolePolicy", policy => policy.RequireAssertion(context =>
context.User.IsInRole("Admin") &&
context.User.HasClaim(claim => claim.Type == "Edit Role" && claim.Value == "true") ||
context.User.IsInRole("Super Admin")
));
});
- On the AuthorizationPolicyBuilder instance, use RequireAssertion method instead of RequireClaim or RequireRole
- RequireAssertion() method takes Func<AuthorizationHandlerContext, bool> as a parameter
- This Func takes AuthorizationHandlerContext as input parameter and returns a boolean
- The AuthorizationHandlerContext instance provides access to the User roles and claims
services.AddAuthorization(options =>
{
options.AddPolicy("EditRolePolicy", policy =>
policy.RequireAssertion(context => AuthorizeAccess(context)));
});
private bool AuthorizeAccess(AuthorizationHandlerContext context)
{
return context.User.IsInRole("Admin") &&
context.User.HasClaim(claim => claim.Type == "Edit Role" && claim.Value == "true") ||
context.User.IsInRole("Super Admin");
}
{
options.AddPolicy("EditRolePolicy", policy =>
policy.RequireAssertion(context => AuthorizeAccess(context)));
});
private bool AuthorizeAccess(AuthorizationHandlerContext context)
{
return context.User.IsInRole("Admin") &&
context.User.HasClaim(claim => claim.Type == "Edit Role" && claim.Value == "true") ||
context.User.IsInRole("Super Admin");
}
No comments:
Post a Comment