Authentication and Authorization in ASP.NET Core

This tutorial covers the fundamental concepts and implementation of authentication and authorization in ASP.NET Core applications.

Understanding the Concepts

Authentication is the process of verifying who a user is. It confirms their identity, typically through credentials like username/password, tokens, or social logins.

Authorization is the process of determining what an authenticated user is allowed to do. It enforces access controls based on roles, permissions, or policies.

Core Components

Implementing Authentication

1. Setting up ASP.NET Core Identity

Add the necessary NuGet packages:

dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore

Configure the Identity service in Program.cs:

builder.Services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

            builder.Services.AddIdentity<ApplicationUser, IdentityRole>(options => options.SignIn.RequireConfirmedAccount = true)
                .AddEntityFrameworkStores<ApplicationDbContext>();

Configure the Identity middleware in Program.cs:

app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthentication(); // Must come before UseAuthorization
            app.UseAuthorization();

            app.MapRazorPages();
            app.MapControllers();

            app.Run();

2. User Registration and Login

ASP.NET Core Identity scaffolding provides ready-to-use pages for registration, login, logout, and password management.

Run the following command in your project directory:

dotnet aspnet-codegenerator identity -u User -p IdentityUser --dbContext-type ApplicationDbContext --outdir Pages/Account

Implementing Authorization

1. Role-Based Authorization

Assign roles to users. You can do this programmatically or through the Identity UI.

Use the [Authorize] attribute to protect endpoints:

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

In Razor Pages or Views, use the asp-page-authorize or asp-controller-authorize tag helpers.

2. Claim-Based Authorization

Claims represent attributes about the user. For example, a claim could be the user's department or employee ID.

Add a claim during user creation or update:

await _userManager.AddClaimAsync(user, new Claim(ClaimTypes.Department, "Sales"));

Authorize based on claims:

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

3. Policy-Based Authorization

Define custom authorization policies in Program.cs.

builder.Services.AddAuthorization(options =>
            {
                options.AddPolicy("SalesDepartmentPolicy", policy =>
                    policy.RequireClaim(ClaimTypes.Department, "Sales"));

                options.AddPolicy("MinimumAgePolicy", policy =>
                    policy.RequireAssertion(context =>
                    {
                        var ageClaim = context.User.FindFirst(c => c.Type == ClaimTypes.DateOfBirth);
                        if (ageClaim != null)
                        {
                            var dob = DateTime.Parse(ageClaim.Value);
                            int age = DateTime.Today.Year - dob.Year;
                            if (dob.Date > DateTime.Today.AddYears(-age)) age--;
                            return age >= 18;
                        }
                        return false;
                    }));
            });

Securing Endpoints

Apply authorization attributes to controllers or individual actions:

[Authorize] // Requires any authenticated user
            public class SecretController : Controller
            {
                [Authorize(Roles = "Editor")] // Requires user in 'Editor' role
                public IActionResult Edit() { ... }

                [Authorize(Policy = "CanPublishArticle")] // Requires custom policy
                public IActionResult Publish() { ... }
            }

User Interface Considerations

In your UI, conditionally render elements based on user authentication status and roles/claims.

Example in Razor:

@if (User.Identity.IsAuthenticated)
            {
                <p>Hello, @User.Identity.Name!</p>
                @if (User.IsInRole("Admin"))
                {
                    <a href="/Admin">Admin Panel</a>
                }
            }
            else
            {
                <a href="/Account/Login">Login</a>
                <a href="/Account/Register">Register</a>
            }

Further Reading