Authentication and authorization in ASP.NET Core

Schemes, cookies vs tokens, CSRF, policies with handlers, Identity details and the mistakes interviewers ask about.

Authentication and authorization in ASP.NET Core

Authentication answers who is this user?; authorization answers may this user do this? This article covers the details interviewers ask about.

Cookies or tokens?

  • Cookie (server-rendered web apps): the browser sends it automatically. Mark it HttpOnly (JavaScript can’t read it), Secure (HTTPS only) and SameSite. Because the browser sends it on its own, forms need anti-forgery tokens against CSRF.
  • Bearer token / JWT (APIs, mobile apps): the client adds Authorization: Bearer … itself, so CSRF doesn’t apply; but a token kept in browser localStorage can be stolen by an XSS script.
  • The API checks every JWT: issuer, audience, expiry and signing key. Keep access tokens short-lived and use refresh tokens that are rotated and can be revoked.

Status codes

On an endpoint that requires a user: no valid login → 401 (challenge), logged in but not allowed → 403 (forbid). A bad token on an anonymous endpoint just runs as an anonymous request. With cookie login, web pages are redirected (302) to the login or access-denied page; since .NET 10, known API endpoints get 401/403 instead.

Policies with requirements and handlers

A policy is a named set of requirements. Each requirement has a handler with your logic, such as “is over 18” or “is in the sales department”:

var user = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim("department", "sales") }, "demo"));
bool canRefund = user.HasClaim("department", "sales") || user.IsInRole("Admin");
Console.WriteLine(canRefund);

It prints True: the check a handler would make. For rules about one specific object (“may edit this order”), use resource-based authorization with IAuthorizationService.AuthorizeAsync(user, order, "CanEdit").

Identity facts worth knowing

  • Passwords are stored as PBKDF2 hashes, salted and iterated; never write your own hashing.
  • Lockout only counts failures when sign-in is called with lockoutOnFailure: true.
  • The store is pluggable; the usual one is EF Core with SQL Server.
  • MapIdentityApi (.NET 8+) gives ready-made login endpoints that issue Identity’s own bearer tokens (not JWTs). Identity is not an OAuth/OpenID Connect server; for single sign-on use an identity provider such as Microsoft Entra ID.

Mistakes interviewers ask about

  • Authorization middleware before authentication: every user looks anonymous.
  • Secrets inside a JWT: it is only encoded, anyone can read it.
  • Forms without anti-forgery tokens when using cookies.
  • [Authorize(Roles = "A,B")] means A or B; two [Authorize] attributes mean both.

Read more: https://learn.microsoft.com/en-us/aspnet/core/security/authorization/introduction

#tip · TIP-087


Write a comment