Understanding All Types of Authorization in ASP.NET Core

A developer's guide to Role-Based, Claim-Based and Attribute-Based Authorization with real-world use cases

Posted by Hüseyin Sekmenoğlu on June 02, 2021 Application Security Backend Development

Authorization in ASP.NET Core is flexible and powerful.
You can secure your applications using multiple techniques based on roles, claims, attributes or even complex logic tied to the current resource.

Here are all the main types of authorization in ASP.NET Core.


๐Ÿ”‘ 1. Role-Based Authorization (RBAC)

Use this when your application has fixed roles like Admin, Manager or User.

[Authorize(Roles = "Admin")]
public IActionResult AdminOnly()
{
    return View();
}

You define roles during authentication and check them declaratively with [Authorize].

โœ… Simple to implement
โŒ Hard to scale with complex permissions


๐Ÿงพ 2. Claim-Based Authorization

This works on user claims such as "Department", "Region", "SubscriptionLevel".

[Authorize(Policy = "HROnly")]
public IActionResult HRDashboard()
{
    return View();
}

Policy is configured in Program.cs or Startup.cs:

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("HROnly", policy =>
        policy.RequireClaim("Department", "HR"));
});

โœ… More flexible than roles
โŒ Still limited for complex logic


โš™๏ธ 3. Policy-Based Authorization

This is a broader system that includes roles, claims and custom requirements.

You can create policies using:

  • RequireRole

  • RequireClaim

  • RequireAssertion

  • Custom IAuthorizationRequirement and AuthorizationHandler

options.AddPolicy("Over18", policy =>
    policy.RequireAssertion(context =>
        context.User.HasClaim(c =>
            c.Type == "Age" && int.Parse(c.Value) >= 18)));

โœ… Centralized and composable
โŒ Slightly more complex setup


๐Ÿงฉ 4. Resource-Based Authorization

Use this when access depends on a specific object or instance.

public class DocumentAuthorizationHandler : AuthorizationHandler<OperationAuthorizationRequirement, Document>
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
        OperationAuthorizationRequirement requirement, Document resource)
    {
        if (resource.OwnerId == context.User.Identity.Name)
        {
            context.Succeed(requirement);
        }

        return Task.CompletedTask;
    }
}

Then use in controller:

var authResult = await _authorizationService.AuthorizeAsync(User, document, "EditPolicy");

โœ… Good for per-resource access
โŒ Requires custom handlers and service injection


๐Ÿงฌ 5. Attribute-Based Access Control (ABAC)

ABAC is not a built-in feature but can be implemented using policies and custom handlers.

You evaluate access based on user attributes, resource attributes and context attributes.

Example logic:

  • User.Age >= Resource.MinimumAge

  • User.Country == Resource.AvailableInCountry

  • Request.Time between 9AM and 5PM

This often overlaps with resource-based authorization but with more dynamic inputs.

โœ… Most flexible
โŒ Most complex to manage


๐Ÿง  Summary Table

Type

Use Case

Flexibility

Complexity

Role-Based (RBAC)

Simple role access like Admin

Low

Low

Claim-Based

Checks user properties

Medium

Low

Policy-Based

Composable roles and claims

High

Medium

Resource-Based

Object-specific authorization

High

High

Attribute-Based

Attribute and context-driven logic

Very High

Very High


๐Ÿงญ Choose Wisely

Start with Role-Based or Claim-Based if your needs are simple.
Move to Policy-Based or Resource-Based when logic becomes more complex.
Use ABAC when access depends on multiple attributes across user and resource context.

Authorization is not just about blocking access.
It is about designing secure and flexible boundaries that grow with your app.