When implementing an API using ASP.NET Core, there’s often a need to authorize that API’s users. Your system might be organized into several separate areas, which provide access to different resources and actions. It’s very likely that not all users are allowed to use all of those areas. Within a single area, a design might require restricted access to data entities themselves. There are many ways to implement such authorization, one of them being declaring custom authorization attributes on controller methods/actions or on controllers as a whole.
In ASP.NET Core MVC, authorization is performed using the AuthorizeAttribute
class. Here’s a simple example using role-based authorization:
Users with the Admin
or the Moderator
role will have access to the actions in the AdminController
.
While there’s nothing wrong with this, and it gets the job done, the "Admin,Moderator"
string—like you might imagine—is a good recipe for a typo. So let’s move the role names to a set of string constants:
The AdminController
now becomes:
Not ideal, I know. Unfortunately, we can’t use interpolated strings like $"{RoleConstants.Admin},{RoleConstants.Moderator}"
with attributes.
This is a good example where extending the AuthorizeAttribute
class makes sense. Since we’re trying to make it easier to call for role-based authorization on a controller or action, let’s create a custom AuthorizeByRoleAttribute
:
We can use it as follows:
Conclusion
Using custom attributes is a very practical and clean way to implement a custom authorization system for your ASP.NET Core API. It reduces the amount of redundant code and allows developers to make the permissions as granular as needed. By simple adjustments to Swagger (if it’s used), the front-end developers can also easily see which permissions an API method requires.