Authorization in ASP

iamprovidence
4 min readNov 2, 2022

--

In the previous article we have discussed how to implement authentication in ASP, this time we will focus on authorization.

You may also be interested in the Authentication theory:

For those who are new here, it is heavily recommended to read previous posts, since we will continue enhancing the same example.

Also, do not forget to check out some others stories:

  • What is authentication schema in ASP about?
  • Authorization policy under the hood
  • Encapsulate authentication with DelegatingHandler
  • How to parse token on client side

And without any further ado, let’s get started

A little about our domain…

Our customer is really happy about how greatly everything turned out with our previous task. The business is blooming. It is time to add admin panel where we could easily create new products. Of course, it is important that only admin can access that page. And since you already showed yourself like experienced identity engineer, it is likely that you will implement that task 😃

Authorization

So, you don't need to switch a lot between articles, we will do recap of our terminology once again:

Authentication (AuthN) — is the process of defining who user is

Authorization (AuthZ) — is the process of defining what permissions user has

This time, we will primary focusing on authorization.

Roles

Do you remember that Authenticate() method? We will change it a little by adding information about user’s role (line 12). Great thing that it is one of those claims that is supported by default, so we don’t need to come up with any funky name:

Now when roles are part of our cookies, we could manually check whenever it is present and redirect a user to access denied page if it not there. But there are a bit more elegant approach, we can just specify required roles in our attribute [Authorize(Roles = “Admin, User”)]:

Policies

Another successfully closed task 😏

Satisfied with your work, the customer wants to add another page. This time, only those users whose name starts with “J” should have access to it.

What the hell is wrong with you? 😧 Alright, it is not our job to argue customer needs. Let’s just implement that.

Seems like roles are not enough anymore.

The naive approach would be to do everything manually:

However, the things can go messy really quickly. It is unlikely that our Tech Lead would approve that. So after a little bit of investigation, we find out about such thing as policy. Let’s give it a try.

For that, we need to go back to Startup.cs and add the next line:

Here we define the name for our policy and rules which should be satisfied to met it.

This time, our controller looks much cleaner. Just need to specify our policy in [Authorize] attribute:

Every time we need to update those rules, we would need to update a single policy instead of modifying each action in our controller. Now that is something we can show to our Tech Lead 😍

As you can see there are variety method which allows you to validate policy like RequireAuthenticatedUser(), RequireClaim(key, value), RequireRole(roles) etc. RequireAssertion() is so agile that you can define any custom logic you like. But sometimes even those are not enough, so you can define your own requirements.

Custom policy requirements

Happy customer was so satisfied that he have not even noticed as he promised to sell alcohol and cigarette in his store. 😟

Alright, alright, we also will do that. Just remember that page with those products can only be access if you are an adult. Buying cigarette is allowed from 18 years, while alcohol from 20.

I foreshadow the future, and knew something like this going to happen. Therefore, I have already added a date of birth claim to a cookie during Authenticate() method. Your job is to implement requirements:

Seems like it is a perfect use case for custom requirements which can be done using AddRequirements() method. After investigation, you quickly realized it needs IAuthorezationRequirement to work. So, let’s implement one. Gladly, it just marker interface, so we don’t need to do anything fancy. Think about as a collection of data parameters that a policy can use later.

Next step would be to implement AuthorizationHandler for that requirements.

Later, our policies can be registered and used over controller as follows:

You can have multiple custom requirements for one policy. In that case, policy will success only if all the requirements are met.

Just remember kids, alcohol and cigarette are harmful for your health 👮

Conclusion

In this article, we covered quite a lot about authorization. We started with something simple like roles and slowly moved to policies and custom requirements.

Thanks for reading. Hope you enjoyed it. Further — more.

Don't forget to clap 👏

Support ☕️

And Follow to not miss future articles ✅

--

--

iamprovidence

👨🏼‍💻 Full Stack Dev writing about software architecture, patterns and other programming stuff https://www.buymeacoffee.com/iamprovidence