Authorization and Authentication in C# (.NET): A Complete Guide
Web application security is a cornerstone of modern development. In the C# (.NET) ecosystem, built-in authentication and authorization mechanisms allow you to flexibly and reliably protect your application. In this article, we will break down key concepts, tools, and code examples for working with Identity, JWT, and the role-based model.
1. Basic Concepts
Before moving to code, it is important to distinguish between two terms:
- Authentication — the process of verifying a user's identity (who are you?). It is usually done via login/password, tokens, or external providers.
- Authorization — the process of determining access rights (what are you allowed to do?). It is implemented through roles, policies, or claims.
2. ASP.NET Core Identity — Built-in Solution
Microsoft.AspNetCore.Identity is a full-featured user management system that includes registration, login, password reset, two-factor authentication, and much more. It works with Entity Framework Core and supports any data stores.
Installation:
dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCoredotnet add package Microsoft.EntityFrameworkCore.SqlServerExample of user registration (Account controller):
public class AccountController : Controller{ private readonly UserManager<IdentityUser> _userManager; private readonly SignInManager<IdentityUser> _signInManager;
public AccountController(UserManager<IdentityUser> userManager, SignInManager<IdentityUser> signInManager) { _userManager = userManager; _signInManager = signInManager; }
[HttpPost] public async Task<IActionResult> Register(RegisterViewModel model) { if (ModelState.IsValid) { var user = new IdentityUser { UserName = model.Email, Email = model.Email }; var result = await _userManager.CreateAsync(user, model.Password); if (result.Succeeded) { await _signInManager.SignInAsync(user, isPersistent: false); return RedirectToAction("Index", "Home"); } foreach (var error in result.Errors) ModelState.AddModelError(string.Empty, error.Description); } return View(model); }}3. JWT (JSON Web Tokens) — Stateless Authentication
For modern SPAs (React, Angular) or mobile applications, JWT is often used. The token is signed by the server and contains claims about the user. The server does not store sessions, which simplifies scaling.
Configuration in Program.cs:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer = builder.Configuration["Jwt:Issuer"], ValidateAudience = true, ValidAudience = builder.Configuration["Jwt:Audience"], ValidateLifetime = true, IssuerSigningKey = new SymmetricSecurityKey( Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])) }; });Token generation:
public string GenerateToken(IdentityUser user){ var claims = new[] { new Claim(ClaimTypes.NameIdentifier, user.Id), new Claim(ClaimTypes.Email, user.Email), new Claim(ClaimTypes.Role, "User") };
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"])); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
va