SecurityMVCRBACAugust 2026 ยท 8 min read

Role-Based Authorization in ASP.NET Core MVC: Roles, Policies, and Claims

TL;DR

Role-based authorization in ASP.NET Core MVC is built on Identity roles plus the [Authorize] attribute, extended with claims and policies for fine-grained control. Seed Guest/Member/Admin roles, assign users at registration, and protect controllers, actions, and endpoints with a few attributes.

Authentication answers who are you? Authorization answers what may you do? In ASP.NET Core MVC, role-based authorization (RBAC) is the first and simplest answer: users are grouped into roles, and controllers, actions, and endpoints declare which roles may use them. This guide implements complete RBAC in .NET 10 โ€” seeding roles, assigning users, protecting routes, and layering claims and policies on top when roles alone are not enough.

Seeding Roles and an Admin User

Roles should exist before any user logs in. Seed Guest, Member, and Admin at startup, and create the first admin user:

public static async Task SeedAsync(IServiceProvider services)
{
    var roles = services.GetRequiredService<RoleManager<IdentityRole>>();
    var users = services.GetRequiredService<UserManager<AppUser>>();

    foreach (var name in new[] { "Guest", "Member", "Admin" })
        if (!await roles.RoleExistsAsync(name))
            await roles.CreateAsync(new IdentityRole(name));

    var admin = await users.FindByEmailAsync("admin@root.com");
    if (admin is null)
    {
        admin = new AppUser { UserName = "admin@root.com", Email = "admin@root.com" };
        await users.CreateAsync(admin, "Admin@123456");
    }
    if (!await users.IsInRoleAsync(admin, "Admin"))
        await users.AddToRoleAsync(admin, "Admin");
}

Assigning Roles at Registration

New users start with the least privilege. Assign the Guest or Member role the moment the account is created so no user is ever created without a role:

var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
    await _userManager.AddToRoleAsync(user, "Member");
    await _signInManager.SignInAsync(user, isPersistent: true);
}

Protecting Controllers and Actions with [Authorize(Roles)]

Apply the attribute at controller or action level. Multiple roles are separated by commas; multiple attributes combine with AND:

[Authorize]                                   // any signed-in user
public class DashboardController : Controller { }

[Authorize(Roles = "Admin")]                  // admins only
public class UsersController : Controller { }

[Authorize(Roles = "Admin,Manager")]          // either role
public class ReportsController : Controller { }

[Authorize]
public class OrdersController : Controller
{
    [Authorize(Roles = "Admin")]
    public IActionResult Delete(int id) { /* ... */ }
}

Razor views can also conditionally render UI with @User.IsInRole("Admin"), and Minimal API endpoints use .RequireAuthorization("Admin") or .RequireAuthorization(new[] { "Admin", "Manager" }).

Going Beyond Roles: Claims and Policies

Roles are coarse. When access depends on facts โ€” a department, a tenant, an approval right โ€” switch to claims and policies:

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("FinanceOnly", policy =>
        policy.RequireClaim("Department", "Finance"));

    options.AddPolicy("CanApprove", policy =>
        policy.RequireAssertion(ctx =>
            ctx.User.IsInRole("Admin") ||
            ctx.User.HasClaim(c => c.Type == "CanApprove" && c.Value == "true")));
});

Apply with [Authorize(Policy = "FinanceOnly")]. Because policies can combine roles and claims, they give you a smooth upgrade path from pure RBAC to fine-grained, claim-based authorization.

Key Takeaways

  • Seed roles before users and assign every new user to the least-privileged role
  • [Authorize] and [Authorize(Roles = "...")] protect controllers, actions, and endpoints
  • Combine multiple attributes to require role membership and other conditions together
  • Move to claims and policies when roles alone are too coarse
  • Authorization stays declarative and inspectable from attribute to endpoint

FAQ

What is the difference between roles and claims? A role is a coarse grouping ("Admin"). A claim is a fact about the user ("Department = Finance"). Policies can evaluate either or both.

Does [Authorize(Roles = "Admin,Manager")] mean the user needs both roles? No, a comma-separated list means either role. To require both, stack two attributes.

Can I protect Minimal API endpoints with roles? Yes, use .RequireAuthorization("Admin") on the route group or individual endpoint.

How do I show or hide UI based on roles? In Razor views use @if (User.IsInRole("Admin")) or the AuthorizeView pattern for conditional rendering.

See RBAC implemented across a real MVC codebase?

MVC EDevKit Basic ships Guest, Member, and Admin roles with seeded admin, role-protected controllers and endpoints, plus claims-based policies. $21.

View MVC EDevKit Details