The goal of this post is to show how can we protect controller actions in ASP.NET Core 1 using Policies.
The whole code is available on GitHub: ASP.NET Core 1, Security using Policies.
With policies we don’t need to hard code anymore Roles or Names in our Authorize attribute. A policy is an authorization logic that contains one of more requirements.
How to use a policy?
The concept is very simple, once we have a defined policy we can add it to our Authorize attributes…
How to create a policy?
We have to define our policies in our Startup class, in ConfigureServices. We need a policy name, a list of valid authentication schemes and a list of requirements.
|// Configure authorization|
|services.AddAuthorization(options => options.AddPolicy(CookieMonsterSecurity.OnlyGoodMonstersPolicy, policy =>|
|// Our own requirement logic...|
We can add more than one requirement to our policy, there are some pre-build requirements:
But the more flexible way is to add a custom requirement, doing this we can write our own logic:
- policy.AddRequirements(new IsGoodMonsterRequirement());
To write our requirement we use the base class AuthorizationHandler and implement the interface IAuthorizationRequirement.
This requirement checks that the user is authenticated and has the claim “MonsterTypeClaim” = “Good”
|public class IsGoodMonsterRequirement : AuthorizationHandler<IsGoodMonsterRequirement>, IAuthorizationRequirement|
|protected override void Handle(AuthorizationContext context, IsGoodMonsterRequirement requirement)|
|Console.WriteLine("Is a good monster?");|
|Console.WriteLine("... is authenticated...");|
|if (context.User.HasClaim(CookieMonsterSecurity.MonsterTypeClaim, CookieMonsterSecurity.MonsterTypes.Good))|
|Console.WriteLine("... and has the MonsterTypeClaim = MonsterTypes.Good!");|
Pingback: Authorization Policies and Data Protection with IdentityServer4 in ASP.NET Core | Software Engineering
Previos I have used a custom filter as this sample:
[AlfaClaim(Module = AuthorizationModule.ORGANIZATION, RequiredClaim = AM.Create | AM.Read |AM.Update)]
I pass parameters to the filter which module and what operation to check the users privilege against. BUT I can’t figure out how to pass parameters to a custom requirement, any idea how to solve this?
Everyting was easy with custom filter but the new Authorization feels a bit over engineered.