100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
C#

Authentication with ASP.NET Core Identity

Learn how ASP.NET Core Identity manages users, passwords, and cookie-based sign-in for server-rendered and hybrid applications.

SecurityIntermediate10 min readJul 10, 2026
Analogies

What Is ASP.NET Core Identity

ASP.NET Core Identity is a full membership system built into the framework that handles user storage, password hashing, and sign-in state for your application. Instead of writing your own user table and hashing routine, you register IdentityUser (or a custom subclass) with an EF Core-backed IdentityDbContext, and the framework gives you UserManager<TUser> for account operations like CreateAsync and CheckPasswordAsync, and SignInManager<TUser> for turning a successful credential check into an authenticated session.

🏏

Cricket analogy: Just as the BCCI doesn't let every club run its own player registration system and instead mandates a central database of verified players, Identity centralizes user records instead of every controller inventing its own ad-hoc user table.

Setting Up Identity

You wire up Identity in Program.cs by calling builder.Services.AddIdentity<IdentityUser, IdentityRole>() (or AddDefaultIdentity for Razor Pages scaffolding), chaining .AddEntityFrameworkStores<AppDbContext>() to persist users and roles through EF Core, and .AddDefaultTokenProviders() for features like password reset and email confirmation tokens. This requires an EF Core migration to create the AspNetUsers, AspNetRoles, and related join tables, and it configures a default cookie authentication scheme unless you override it.

🏏

Cricket analogy: Setting up Identity is like a franchise registering with the BCCI before a season starts — you configure the ground rules (password rules, token providers) once via AddIdentity, then every match (request) follows them automatically.

When a user submits credentials, a controller or Razor Page calls SignInManager.PasswordSignInAsync(username, password, isPersistent, lockoutOnFailure: true). Internally this calls UserManager.CheckPasswordAsync to verify the hashed password, increments AccessFailedCount on failure, and on success issues an encrypted authentication cookie containing the user's claims. Subsequent requests carry that cookie, and the CookieAuthenticationMiddleware reconstructs the ClaimsPrincipal on HttpContext.User without hitting the database on every request.

🏏

Cricket analogy: PasswordSignInAsync is like the third umpire reviewing a run-out appeal — it checks the evidence (password hash) once, and once cleared, the on-field decision (the auth cookie) stands for the rest of the innings without re-review every ball.

csharp
// Program.cs
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("Default")));

builder.Services.AddIdentity<IdentityUser, IdentityRole>(options =>
{
    options.Password.RequiredLength = 10;
    options.Password.RequireNonAlphanumeric = true;
    options.Lockout.MaxFailedAccessAttempts = 5;
    options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(15);
    options.SignIn.RequireConfirmedEmail = true;
})
.AddEntityFrameworkStores<AppDbContext>()
.AddDefaultTokenProviders();

var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();

// AccountController.cs
[HttpPost]
public async Task<IActionResult> Login(LoginModel model)
{
    var result = await _signInManager.PasswordSignInAsync(
        model.Email, model.Password, model.RememberMe, lockoutOnFailure: true);

    if (result.Succeeded)
        return RedirectToAction("Index", "Home");

    if (result.IsLockedOut)
        return View("Lockout");

    ModelState.AddModelError(string.Empty, "Invalid login attempt.");
    return View(model);
}

ASP.NET Core provides a pre-built Identity UI as a Razor Class Library, scaffoldable via 'dotnet aspnet-codegenerator identity'. It gives you working login, register, and password-reset pages out of the box, which you can then override page-by-page as your design needs diverge from the default.

Password Hashing and Lockout Options

Identity never stores plaintext passwords. PasswordHasher<TUser> uses PBKDF2 with HMAC-SHA256, a random 128-bit salt per user, and a configurable iteration count (10,000 by default in newer versions) to make brute-force attacks computationally expensive. IdentityOptions also expose Lockout settings — MaxFailedAccessAttempts and DefaultLockoutTimeSpan — so repeated bad password attempts temporarily lock the account rather than allowing unlimited guessing, and Password options enforce minimum length, character-class requirements, and uniqueness against recently used passwords.

🏏

Cricket analogy: PBKDF2's repeated hashing rounds are like a bowler running through thousands of net sessions before a match — each round makes the final delivery (hash) harder to reverse-engineer, just as iteration count slows down brute-force attempts.

Always serve authentication pages over HTTPS and set CookieOptions.SecurePolicy to CookieSecurePolicy.Always in production. A password or session cookie sent over plain HTTP can be captured by anyone on the same network, completely bypassing PBKDF2's protection.

  • ASP.NET Core Identity centralizes user storage, password hashing, and sign-in through UserManager<TUser> and SignInManager<TUser>.
  • AddIdentity<TUser, TRole>().AddEntityFrameworkStores<TContext>() wires Identity to an EF Core database and requires a migration.
  • PasswordSignInAsync verifies credentials and issues an encrypted authentication cookie carrying the user's claims.
  • Passwords are hashed with PBKDF2, a per-user random salt, and a configurable iteration count — never stored in plaintext.
  • Lockout settings (MaxFailedAccessAttempts, DefaultLockoutTimeSpan) throttle brute-force login attempts.
  • The scaffoldable Identity UI Razor Class Library provides working login/register/reset pages you can override individually.
  • Cookies must be transmitted only over HTTPS with SecurePolicy set to Always to prevent interception.

Practice what you learned

Was this page helpful?

Topics covered

#ASPNETCoreStudyNotes#MicrosoftTechnologies#AuthenticationWithASPNETCoreIdentity#Authentication#ASP#NET#Core#Security#StudyNotes#SkillVeris