Skip to content
ExponaBLOG
.NET & ASP.NET CORE · DAY 032 / 100

ASP.NET Core Identity: when to use it, explained simply

Build, buy, or Identity? An honest breakdown.

Expona Admin7 min read

ASP.NET Core Identity: when to use it

You're building a new application and someone asks, "How are we handling authentication?" Suddenly you're standing at a fork: roll your own user database, buy a third-party provider, or use ASP.NET Core Identity. The honest answer is that there's no one-size-fits-all solution—but making the wrong choice now costs you weeks of refactoring later.

Over the past few years, I've watched teams waste time reinventing password hashing in production, implement their own 2FA and get it wrong, and maintain duplicate user databases across three systems. At the same time, I've seen smaller teams embrace a managed identity service and ship features instead of worrying about security compliance. The pattern is clear: the right identity solution depends on your constraints, not your preferences.

The three approaches: compare what they are and when they fit

Let me lay out the three main paths you can take and be honest about the trade-offs.

Approach Best for Main benefit Main cost
ASP.NET Core Identity Startups, smaller platforms, greenfield projects, internal tools Built into .NET ecosystem, free, auditable code You maintain security updates, compliance, lockout logic
Entra ID / Auth0 / Cognito Enterprise teams, multi-app ecosystems, strict compliance, SSO requirement Offload security burden, managed 2FA, audit logs, compliance ready Monthly costs per user, vendor lock-in, slower iteration on custom logic
Custom JWT (stateless) Microservices, internal APIs, high-volume systems with simple auth needs Lightweight, no user state in database, fast token validation You own token refresh strategy, revocation is hard, no built-in security features

The real question isn't which one is "best"—it's which one fits your context.

ASP.NET Core Identity is your default when you control the entire application stack, users live primarily in one system, and you have the engineering bandwidth to handle security maintenance. I reach for this on greenfield SaaS platforms, internal admin tools, and applications where I want to audit every line of auth code.

Entra ID, Auth0, or AWS Cognito make sense when your organization already owns these platforms, when you need federated sign-in across multiple applications, or when compliance requirements demand a third-party audit trail. If your enterprise team says "everyone uses Entra ID," that decision is already made—fighting it costs more than accepting it.

Custom JWT is my choice for backend-to-backend communication, microservices that need lightweight token validation, or when your auth requirements are so minimal (internal dashboards, B2B APIs with API keys) that a full identity system is overkill.

ASP.NET Core Identity endpoints in .NET 8+: one line to auth

If you land on ASP.NET Core Identity, the latest versions make the setup remarkably lean. In .NET 8, Microsoft added MapIdentityApi<TUser>(), which wires up register, login, and refresh endpoints automatically.

csharp

var builder = WebApplicationBuilder.CreateBuilder(args);

builder.Services.AddIdentityApiEndpoints<ApplicationUser>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

builder.Services.AddAuthentication()
    .AddBearerToken(IdentityConstants.BearerScheme);

var app = builder.Build();

app.MapIdentityApi<ApplicationUser>();
app.MapControllers();
app.Run();

That's it. You now have:

  • POST /register — Accept email and password, hash it, store it.
  • POST /login — Validate credentials, return access and refresh tokens.
  • POST /refresh — Exchange a refresh token for a new access token.

Behind the scenes, Identity handles password hashing with PBKDF2, token generation, and refresh logic. You don't write a single authentication line. On a recent internal project, this saved my team two to three days compared to rolling a custom JWT endpoint.

The endpoints return a standard bearer token (JWT) that you validate on protected routes using the standard .NET authentication middleware. Your controllers don't need to change:

csharp

[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
    [Authorize]
    [HttpGet]
    public async Task<IActionResult> GetMyOrders()
    {
        var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
        // Fetch orders for this user
    }
}

What ASP.NET Core Identity actually does for you

The reason I don't recommend hand-rolling auth isn't because it's hard—it's because it's deceptively easy to get wrong in production.

Password hashing: Identity uses PBKDF2 with a configurable iteration count (100,000 by default in recent versions). If you hash passwords with a single SHA256, you're inviting someone to crack them with a $100 GPU. Identity gives you the right default; changing it is one line if you need Argon2 or bcrypt instead.

Lockout policies: After five failed login attempts, do you lock the account for 15 minutes? Forever? Do you notify the user? Does the count reset? Identity gives you a framework for this. Without it, I've seen systems either vulnerable to brute force or so strict that legitimate users stay locked out.

2FA and email confirmation: Identity scaffolds time-based one-time passwords (TOTP), SMS codes, and email verification tokens. You're not implementing HMAC-SHA1 rolling windows yourself—you're using tested, peer-reviewed code. On a trading platform I worked on, 2FA was non-negotiable; Identity's framework meant we shipped it in two days, not two weeks.

Audit trails: Identity logs security events (login attempts, lockouts, role changes) to its audit table by default. For compliance, this beats fishing through application logs.

Can you build all of this yourself? Yes. Should you? Only if you have a dedicated security engineer and time to spare.

When to skip Identity and integrate with an existing provider

Here's where I see the most waste: teams implementing Identity when their company already has an identity provider running.

If your organization uses Entra ID (formerly Azure AD), Auth0, or Okta, integrating with it typically means:

  1. Adding OpenID Connect (OIDC) middleware to your ASP.NET Core app.
  2. Letting the external provider handle login and returning an ID token and claims.
  3. Storing minimal user info in your local database (just enough to link external ID to your domain objects).

Why? You avoid duplicating user management. When someone leaves the company, IT disables their Entra ID account and they're instantly locked out of all systems, including yours. No stale user records. No "who manages password resets?"

On an e-commerce platform, this wouldn't make sense—your users are customers, not employees. On an internal CRM or admin dashboard for a mid-market company? Integrating with Entra ID is the correct move.

The cost is that you have less direct control over authentication UX. Your login page is hosted by the provider (or you use their hosted UI). Your password reset flow is theirs. For internal tools, this is a feature, not a bug. For public-facing products, it's restrictive.

csharp

// Minimal integration example: OIDC with Entra ID
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddOpenIdConnect(options =>
    {
        options.Authority = "https://login.microsoftonline.com/{tenantId}/v2.0";
        options.ClientId = "your-client-id";
        options.ClientSecret = "your-client-secret";
        options.ResponseType = "code";
        options.Scope.Add("openid");
        options.Scope.Add("profile");
        options.Scope.Add("email");
    });

app.UseAuthentication();
app.UseAuthorization();

After login, the user's claims populate User.Identity.Claims just like they would with Identity. Your authorization code doesn't know the difference.

Common mistakes I've seen teams make

Implementing Identity when you don't need per-user persistence: If your only auth requirement is "microservice A can call microservice B," a shared API key or short-lived JWT between services is simpler than spinning up a user database. I've seen teams add Identity + a full user table for a 15-person internal system, then never use half the features.

Storing sensitive data in JWT claims: A token is readable by the client. Never put salary, subscription tier, or unencrypted payment methods in claims. Use claims only for user ID, email, and role—then look up sensitive data server-side from the database.

Not implementing token refresh properly: An access token should expire in 15–30 minutes. If you give it a 1-year expiry, you've created a liability. Refresh tokens last longer (days or weeks), but they need to be invalidated when a user logs out or changes their password. Identity handles this; a hand-rolled system often doesn't.

Choosing a provider, then underestimating migration cost: If you build with Identity for three years, then your company mandates Entra ID, you'll rewrite your entire auth flow. Happened to a team I know. Pick early, accept it might feel like overkill initially, and move on.

Ignoring password policy: Identity lets you configure minimum length, required special characters, and required uppercase/digits. Set sane defaults. I've seen systems allow 4-character passwords, then act surprised at the breach.

Key takeaways

  • Use ASP.NET Core Identity on greenfield SaaS products, internal tools, and systems where you control the full user lifecycle. It's free, battle-tested, and integrates seamlessly with .NET.
  • Use Entra ID, Auth0, or Cognito when your organization already operates these platforms or when multi-app SSO and compliance audits are non-negotiable. Accept that you trade control for managed security.
  • Use custom JWT only for backend-to-backend communication or genuinely minimal auth scenarios (internal dashboards with API key auth).
  • Leverage MapIdentityApi in .NET 8+ to eliminate boilerplate. You get register, login, and refresh endpoints in five lines of code.
  • Never hand-roll password hashing, 2FA, or lockout logic. These are security-critical and easy to get wrong. Use Identity's implementations or outsource to a provider.
  • If an identity provider already exists in your organization, integrating with it costs less than maintaining a duplicate user database.
  • Make your auth decision early, document it, and stick with it. Migrating between approaches is expensive.
ShareXLinkedInReddit

Found this useful? Support the writing.

Buy me a coffee
Written by
Expona Admin
Site administrator

Comments

Loading comments…

Leave a comment

Comments are reviewed before they appear. Be kind and stay on topic.

Related articles