Don’t Ignore These 4 pillars (Roles, Claims, Policies, Requirements) of Authentication and Authorization in ASP.NET Core

DotNet Full Stack Dev
3 min readSep 3, 2024

--

In ASP.NET Core, authentication and authorization are crucial aspects of securing your application. They ensure that only authorized users can access specific resources or perform certain actions. This blog post will explore four key concepts in ASP.NET Core: Roles, Claims, Policies, and Requirements, and show how they are used in practice with C# code snippets.

Embark on a journey of continuous learning and exploration with DotNet-FullStack-Dev. Uncover more by visiting our https://dotnet-fullstack-dev.blogspot.com reach out for further information.

1. Roles

Roles are used for role-based access control (RBAC). They categorize users into groups with similar permissions, making it easier to manage access based on user roles.

Example Usage

Suppose you have an application where certain actions should only be accessible to users with the “Admin” role. You can use the [Authorize] attribute to enforce this role-based access.

Configuration:

First, configure roles in the Startup.cs or Program.cs file when setting up your authentication:

public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.LoginPath = "/Account/Login";
});

services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy =>
policy.RequireRole("Admin"));
});

services.AddControllersWithViews();
}

Controller Example:

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

In this example, the AdminOnly action is accessible only to users who have the "Admin" role.

2. Claims

Claims represent pieces of information about a user. They are often used for claims-based authorization, where access is granted based on user-specific data.

Example Usage

Let’s say you want to authorize users based on their email domain. You can use claims to store and check this information.

Adding Claims:

Add claims when creating or updating a user:

public async Task<IActionResult> Create()
{
var user = new ApplicationUser { UserName = "user@example.com", Email = "user@example.com" };
var result = await _userManager.CreateAsync(user, "Password123!");

if (result.Succeeded)
{
await _userManager.AddClaimAsync(user, new Claim("EmailDomain", "example.com"));
return RedirectToAction("Index");
}

return View();
}

Using Claims in Authorization:

Define a policy based on claims:

services.AddAuthorization(options =>
{
options.AddPolicy("EmailDomainPolicy", policy =>
policy.RequireClaim("EmailDomain", "example.com"));
});

Controller Example:

[Authorize(Policy = "EmailDomainPolicy")]
public IActionResult DomainSpecific()
{
return View();
}

In this example, the DomainSpecific action is accessible only to users with the EmailDomain claim set to "example.com".

3. Policies

Policies are a collection of requirements that must be satisfied for access to be granted. Policies provide a flexible way to define complex authorization rules.

Example Usage

Define a policy that requires users to be both a “Manager” and have a specific claim.

Configuration:

services.AddAuthorization(options =>
{
options.AddPolicy("ManagerAndEditor", policy =>
policy.RequireRole("Manager")
.RequireClaim("Permission", "Editor"));
});

Controller Example:

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

In this example, access to the ManagerAndEditor action requires the user to have both the "Manager" role and the "Editor" permission claim.

4. Requirements

Requirements are specific conditions that must be met for a policy to be considered successful. They encapsulate the logic needed to enforce a policy.

Example Usage

Create a custom requirement and handler to enforce a requirement based on a user’s age.

Requirement:

public class MinimumAgeRequirement : IAuthorizationRequirement
{
public int MinimumAge { get; }

public MinimumAgeRequirement(int minimumAge)
{
MinimumAge = minimumAge;
}
}

Handler:

public class MinimumAgeHandler : AuthorizationHandler<MinimumAgeRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MinimumAgeRequirement requirement)
{
if (!context.User.HasClaim(c => c.Type == ClaimTypes.DateOfBirth))
{
return Task.CompletedTask;
}

var dateOfBirth = Convert.ToDateTime(context.User.FindFirst(c => c.Type == ClaimTypes.DateOfBirth).Value);
int age = DateTime.Today.Year - dateOfBirth.Year;
if (dateOfBirth > DateTime.Today.AddYears(-age))
{
age--;
}

if (age >= requirement.MinimumAge)
{
context.Succeed(requirement);
}

return Task.CompletedTask;
}
}

Configuration:

services.AddAuthorization(options =>
{
options.AddPolicy("AtLeast18", policy =>
policy.Requirements.Add(new MinimumAgeRequirement(18)));
});

services.AddSingleton<IAuthorizationHandler, MinimumAgeHandler>();

Controller Example:

[Authorize(Policy = "AtLeast18")]
public IActionResult AgeRestricted()
{
return View();
}

In this example, the AgeRestricted action requires that the user be at least 18 years old, as determined by the MinimumAgeRequirement.

Conclusion

Understanding how to use Roles, Claims, Policies, and Requirements in ASP.NET Core allows you to create a robust and flexible authorization system. By leveraging these concepts, you can manage access control efficiently and ensure that users have appropriate permissions based on their roles, claims, and other criteria.

Each component plays a unique role:

  • Roles categorize users into groups with similar permissions.
  • Claims provide specific pieces of information about users.
  • Policies combine multiple requirements to define access rules.
  • Requirements encapsulate specific conditions for policy enforcement.

Implementing these concepts effectively ensures that your application can handle complex authorization scenarios and provide a secure user experience.

--

--

DotNet Full Stack Dev
DotNet Full Stack Dev

Written by DotNet Full Stack Dev

Join me to master .NET Full Stack Development & boost your skills by 1% daily with insights, examples, and techniques! https://dotnet-fullstack-dev.blogspot.com

No responses yet