Role-based Authorization in ASP.NET Core
Tags: aspnetcore, csharp, rolebasedauthorization
Published: 2023-04-05 00:44:41

---
title: Role-based Authorization in ASP.NET Core
published: true
date: 2023-03-06 02:01:16 UTC
tags: ASPNETCore,aspnetcore,csharp,rolebasedauthorization
canonical_url: https://coderethinked.com/role-based-authorization-in-asp-net-core/
---

## What is role-based authorization?

As the name says, role-based authorization authorizes a user based on the role defined to the user.

## Creating roles and users in ASP.NET Core with Identity

For this article, I’ve created a new ASP.NET Core app in .NET 6 with Individual Accounts as the Authentication type, which will create the roles, users, and other tables in the local database.

Here are the user and roles tables. I’ve added a few users and roles for our blog post.

![roles and users](https://coderethinked.com/wp-content/uploads/2023/03/image.png)
_roles and users_

## Configuring role-based authorization in `program.cs` or `startup.cs`

Let’s see how we can use the role-based authorization in the asp.net core web app.

In the `Program.cs` file, we have the following line indicating the default identity is added to the application (this is added to my project by default because I’ve created a brand new one with Individual Accounts)

```csharp
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();
```

We will add `.AddRoles<IdentityRole>()` (The IdentityRole class is part of `Microsoft.AspNetCore.Identity`) to the line which then becomes this.

```csharp
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>();
```

And we’ve to register `useAuthorization()` between `UseRouting` and `UseEndpoints` otherwise, we might run into the following issue.

> Configure your application startup by adding app.UseAuthorization() in the application startup code. If there are calls to app.UseRouting() and app.UseEndpoints(…), the call to app.UseAuthorization() must go between them
> <footer><div></div></footer>

## Decorating controllers and Razor pages for Role-based authorization

Setting the Roles property on the Authorize attributes is how we set the role-based authorization.

Ex: `[Authorize(Roles = "Admin")]`

For controllers, we can decorate the controller class like this

```csharp
[Authorize(Roles = "Admin")]
public class HomeController : Controller
{
  [Route("index")]
  public IActionResult Index()
  {
      return View();
  }
}

```

User having access invoking the Index action will see the below page

![user having access to role](https://coderethinked.com/wp-content/uploads/2023/03/image-1-1024x180.png)
_user having access to role_

The user who does not have access to the Admin role receives the following access denied error.

![user does not have access to role](https://coderethinked.com/wp-content/uploads/2023/03/image-2-1024x216.png)
_user does not have access to role_

Or we can have the Authorize on the action methods too.

```csharp
[Authorize(Roles = "SuperUser")]
[Route("time")]
public IActionResult Time() => Content(new TimeOnly().ToLongTimeString());
```

The user having a superuser role sees the current time on the Time action.

![user have access](https://coderethinked.com/wp-content/uploads/2023/03/image-3.png)
_user has access to superuser role_

A user without a superuser role sees the following accessing the time action.

![user has no access to super user](https://coderethinked.com/wp-content/uploads/2023/03/image-4-1024x269.png)
_user has no access to superuser_

That’s how we add role-based authorization to the controllers.

Similarly, we can add the authorizations to the razor page. But, we cannot add an Authorize attribute on the page handler methods.

Here is the warning if we tried to add the Authorize attribute on the page handler methods.

> “MVC1001 ‘AuthorizeAttribute’ cannot be applied to Razor Page handler methods. It may be applied either to the Razor Page model or applied globally.”

![cannot have authorize on the razor page handler methods](https://coderethinked.com/wp-content/uploads/2023/03/image-5-1024x162.png)
_Error when decorating authorize attribute over the Razor Page handler methods_

## How to apply multiple roles

To apply an OR between the roles to a single action we have to separate the roles by a comma

```csharp
[Authorize(Roles = "SuperUser, Admin")]
public IActionResult Time() => Content(new TimeOnly().ToLongTimeString());
```

The time action is accessible to users who have either SuperUser **_or_** Admin roles

To apply an **AND** between the roles, we stack the `Authorize` attribute on the action/controller.

```csharp
[Authorize(Roles = "SuperUser")]
[Authorize(Roles = "Admin")]
public IActionResult Time() => Content(new TimeOnly().ToLongTimeString());
```

Now, the time action is accessible only to the users who have both SuperUser **_and_** Admin as their roles.

## Using policy-based roles

We can also combine multiple roles using policies and attach it to our controller/action/pages.

This has to be done in the Program.cs before we do the `builder.Build()` step

```csharp
builder.Services.AddAuthorization(options => { 
  options.AddPolicy("SuperUserRights", policy => policy.RequireRole("Admin", "SuperUser", "BackupAdmin")); 
});
```

Applying this policy with `[Authorize(Policy = "SuperUserRights")]` should work for us.

```csharp
[Authorize(Policy = "SuperUserRights")]
public IActionResult Time() => Content(new TimeOnly().ToLongTimeString());
```

## References

- [Role-based authorization](https://learn.microsoft.com/en-us/aspnet/core/security/authorization/roles?view=aspnetcore-7.0)

The post [Role-based Authorization in ASP.NET Core](https://coderethinked.com/role-based-authorization-in-asp-net-core/) appeared first on [Code Rethinked](https://coderethinked.com).