Real-world applications frequently need more precise control, even while Role-Based Authorization manages broad access levels like Admin or User. What happens if access is contingent on a number of factors, such as the user’s age, location, or ownership of the particular resource they are attempting to modify?
ASP.NET Core offers Policy-Based Authorization for these complex situations. A policy, statements, assertions, assertions, constructed.
This is a building that covers everything from scratch.
Step 1: Configuring Policies in Program.cs
Policies are registered inside the dependency injection container when configuring authorization services in Program.cs. You can define policies using declarative helpers (like RequireClaim) or custom assertions.
Add your custom policies right before var app = builder.Build();:
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | using Microsoft.AspNetCore.Authorization; var builder = WebApplication.CreateBuilder(args); // Add standard Identity & MVC services... builder.Services.AddControllersWithViews(); // Register Policy-Based Authorization builder.Services.AddAuthorization(options => { // 1. Department Claim Policy (Must be in Engineering or Support) options.AddPolicy("EmployeeOnly", policy => policy.RequireClaim("Department", "Engineering", "Support")); // 2. Custom Assertion Policy (Must be at least 21 years old based on a claim) options.AddPolicy("AtLeast21", policy => policy.RequireAssertion(context => context.User.HasClaim(c => c.Type == "DateOfBirth") && DateTime.TryParse(context.User.FindFirst(c => c.Type == "DateOfBirth")?.Value, out var dob) && dob.AddYears(21) <= DateTime.Today)); }); var app = builder.Build(); // Pipeline configuration... app.UseAuthentication(); app.UseAuthorization(); |
Step 2: Creating Custom Requirements and Handlers
When your authorization logic requires complex data evaluation or database lookups, built-in assertions aren’t enough. You need a Custom Requirement and an Authorization Handler.
1. Define the Requirement
Create a class implementing IAuthorizationRequirement:
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | using Microsoft.AspNetCore.Authorization; namespace MvcAuthenticationDemo.Authorization { public class MinimumAgeRequirement : IAuthorizationRequirement { public int MinimumAge { get; } public MinimumAgeRequirement(int minimumAge) { MinimumAge = minimumAge; } } } |
2. Implement the Handler
Create a handler inheriting from AuthorizationHandler<TRequirement> that executes your evaluation logic:
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | using Microsoft.AspNetCore.Authorization; using System.Security.Claims; namespace MvcAuthenticationDemo.Authorization { public class MinimumAgeHandler : AuthorizationHandler<MinimumAgeRequirement> { protected override Task HandleRequirementAsync( AuthorizationHandlerContext context, MinimumAgeRequirement requirement) { var dateOfBirthClaim = context.User.FindFirst(c => c.Type == ClaimTypes.DateOfBirth); if (dateOfBirthClaim == null) { return Task.CompletedTask; // Fail authorization implicitly } if (DateTime.TryParse(dateOfBirthClaim.Value, out var dateOfBirth)) { var calculatedAge = DateTime.Today.Year - dateOfBirth.Year; if (dateOfBirth > DateTime.Today.AddYears(-calculatedAge)) { calculatedAge--; } if (calculatedAge >= requirement.MinimumAge) { context.Succeed(requirement); // Mark authorization as successful } } return Task.CompletedTask; } } } |
3. Register the Handler in DI
Register your custom handler alongside your policies in Program.cs:
C#
1 2 3 4 5 6 7 8 9 10 11 12 | using MvcAuthenticationDemo.Authorization; using Microsoft.AspNetCore.Authorization; // Register custom handler builder.Services.AddScoped<IAuthorizationHandler, MinimumAgeHandler>(); builder.Services.AddAuthorization(options => { options.AddPolicy("Over21Only", policy => policy.Requirements.Add(new MinimumAgeRequirement(21))); }); |
Step 3: Applying Policies to Controllers and Action Methods
Once configured, applying a policy to any controller or individual action method is as simple as passing the policy name into the [Authorize] attribute:
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; public class LoungeController : Controller { // Restrict access using the custom age requirement policy [Authorize(Policy = "Over21Only")] public IActionResult BarAccess() { return View(); } // Restrict access using the department claim policy [Authorize(Policy = "EmployeeOnly")] public IActionResult InternalDashboard() { return View(); } } |
Step 4: Evaluating Policies Imperatively in Razor Views
Sometimes you don’t want to block an entire page request with a 403 error, but rather show or hide specific UI components (like an “Edit” or “Delete” button) based on policy evaluation.
Inject IAuthorizationService directly into your Razor view:
HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | @inject Microsoft.AspNetCore.Authorization.IAuthorizationService AuthorizationService <div class="container mt-4"> <h2>Dashboard</h2> @{ // Imperatively evaluate a policy inside the view var authorizationResult = await AuthorizationService.AuthorizeAsync(User, "Over21Only"); } @if (authorizationResult.Succeeded) { <div class="alert alert-success"> <p>Exclusive Content: You are verified to view restricted materials.</p> </div> } else { <div class="alert alert-warning"> <p>You must meet the age requirement to view this section.</p> </div> } </div> |
Conclusion
Policy-Based Authorization shifts your application’s security away from rigid role lists and toward dynamic, rule-driven evaluation. By combining claim assertions, custom requirements, and imperative Razor checks, you can secure complex, enterprise-grade MVC architectures with confidence.
Recommendation for ASP.NET 11.0 Hosting
A solid base for developing online services and applications is ASP.NET Core 11. Before creating an ASP.NET web application, you must be proficient in JavaScript, HTML, CSS, and C#. There are thousands of web hosting providers offering ASP.NET hosting on the market. However, there are relatively few web hosting providers that offer top-notch ASP.NET hosting.
ASP.NET is the best development language in Windows platform, which is released by Microsoft and widely used to build all types of dynamic Web sites and XML Web services. With this article, we’re going to help you to find the best ASP.NET Hosting solution in Europe based on reliability, features, price, performance and technical support. After we reviewed about 30+ ASP.NET hosting providers in Europe, our Best ASP.NET Hosting Award in Europe goes to HostForLIFE.eu, one of the fastest growing private companies and one of the most reliable hosting providers in Europe.
