Security  

Authentication in ASP.NET Core: JWT vs Cookies vs OAuth 2.0 Explained

Authentication is one of the first security features implemented in almost every web application. Whether you're building a REST API, an MVC application, a Single Page Application (SPA), or a microservices platform, choosing the right authentication mechanism directly affects security, scalability, and user experience.

ASP.NET Core supports multiple authentication approaches, including JWT Bearer tokens, Cookie Authentication, and OAuth 2.0/OpenID Connect. Although these technologies are often mentioned together, they solve different problems and are designed for different scenarios.

Rather than treating them as competing technologies, this article explains how each approach works, where it fits, and how to choose the right authentication strategy for your application.

Note: Authentication verifies who a user is, while authorization determines what the authenticated user is allowed to do. Both are required to secure production applications.

Why Choosing the Right Authentication Matters

Using the wrong authentication method can lead to:

  • Poor user experience

  • Security vulnerabilities

  • Difficult integrations

  • Session management issues

  • Scalability limitations

  • Increased maintenance complexity

Selecting the appropriate authentication strategy early reduces future migration effort and improves overall application security.

Authentication Options at a Glance

ASP.NET Core commonly uses the following authentication methods.

AuthenticationBest For
Cookie AuthenticationMVC and Razor Pages applications
JWT Bearer TokensREST APIs and mobile applications
OAuth 2.0Third-party authorization
OpenID ConnectUser authentication with identity providers

Each approach serves a different purpose and should be selected based on application requirements.

Cookie Authentication

Cookie authentication is commonly used in traditional server-rendered web applications.

After a successful login, the server creates an encrypted authentication cookie that is sent with every subsequent request.

sequenceDiagram
    participant User
    participant Browser
    participant Server

    User->>Server: Login
    Server-->>Browser: Authentication Cookie
    Browser->>Server: Request + Cookie
    Server-->>Browser: Protected Response

Configure cookie authentication.

builder.Services
    .AddAuthentication("Cookies")
    .AddCookie(options =>
    {
        options.LoginPath = "/Account/Login";
        options.AccessDeniedPath = "/Account/Denied";
    });

Cookie authentication is ideal when the browser and server belong to the same application.

JWT Bearer Authentication

JSON Web Tokens (JWT) are widely used for APIs because authentication information is stored inside a signed token instead of a server-side session.

Configure JWT authentication.

builder.Services
    .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.Authority = "https://identity.example.com";

        options.Audience = "api";
    });

Clients include the token with each request.

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

JWT authentication works well for:

  • Mobile applications

  • Single Page Applications

  • Microservices

  • Public APIs

  • Machine-to-machine communication

OAuth 2.0

OAuth 2.0 is an authorization framework that allows applications to access resources on behalf of a user without exposing the user's password.

Common examples include:

  • Sign in with Microsoft

  • Sign in with Google

  • GitHub authentication

  • Microsoft Graph access

  • Google Drive integration

OAuth primarily focuses on delegated authorization rather than user authentication.

OpenID Connect

OpenID Connect (OIDC) extends OAuth 2.0 by adding an identity layer.

It provides:

  • User authentication

  • Identity tokens

  • Standard user profile claims

  • Single Sign-On (SSO)

Modern identity providers such as Microsoft Entra ID, Auth0, Okta, and Keycloak support OpenID Connect.

Authentication Flow Comparison

flowchart LR

A[User]

A --> B[Cookie Login]
A --> C[JWT Login]
A --> D[OpenID Connect]

B --> E[Encrypted Cookie]
C --> F[Access Token]
D --> G[Identity Token]

Each authentication method returns different credentials depending on the application's architecture.

Feature Comparison

FeatureCookiesJWTOAuth 2.0
Browser applications
REST APIs
Stateless
Third-party login
Single Sign-OnLimitedLimited✅ (with OIDC)
Server session requiredYesNoNo

The best choice depends on how users interact with your application.

Protecting API Endpoints

Authorize protected endpoints using the Authorize attribute.

[Authorize]
[ApiController]
[Route("api/orders")]
public class OrdersController : ControllerBase
{
}

ASP.NET Core automatically validates the authenticated user's identity before executing the action.

Common Production Mistakes

ProblemRoot Cause
Storing JWTs insecurelyTokens saved in unsafe browser storage
Session hijackingInsecure cookie configuration
Expired tokens rejectedMissing refresh token strategy
Mixing authentication schemesIncorrect middleware configuration
Weak securityHTTPS not enforced
Authorization failuresMissing or incorrect claims

Most authentication issues arise from configuration mistakes rather than framework limitations.

Best Practices

  • Always enforce HTTPS.

  • Use short-lived access tokens.

  • Store cookies securely using HttpOnly and Secure.

  • Validate JWT issuer and audience.

  • Implement refresh tokens where appropriate.

  • Apply the principle of least privilege.

  • Enable Multi-Factor Authentication whenever possible.

Common Anti-Patterns

Avoid these common mistakes:

  • Creating custom authentication protocols unnecessarily.

  • Storing sensitive information inside JWT payloads.

  • Disabling token validation during development and forgetting to re-enable it.

  • Using long-lived access tokens.

  • Sharing authentication secrets across environments.

  • Treating OAuth 2.0 as an authentication protocol without OpenID Connect.

FAQ

Should I use Cookies or JWT for an ASP.NET Core API?

For browser-based MVC applications, cookies are typically the better choice. For REST APIs consumed by mobile apps, SPAs, or external clients, JWT Bearer authentication is generally more appropriate.

Is OAuth 2.0 the same as OpenID Connect?

No. OAuth 2.0 handles authorization, while OpenID Connect builds on OAuth 2.0 to provide user authentication and identity information.

Can an application use multiple authentication schemes?

Yes. ASP.NET Core supports multiple authentication schemes simultaneously, allowing different endpoints to use cookies, JWTs, or external identity providers.

Are JWT tokens encrypted?

Not by default. JWTs are typically signed to prevent tampering, but their contents can usually be decoded. Avoid storing sensitive information in the token payload.

Conclusion

Authentication is a foundational aspect of application security, and ASP.NET Core provides flexible options for different application architectures. Cookie Authentication remains an excellent choice for traditional web applications, JWT Bearer authentication is well suited for APIs and distributed systems, and OAuth 2.0 with OpenID Connect enables secure integration with modern identity providers.

Understanding the strengths and limitations of each approach helps you choose the right authentication strategy, improve security, and build applications that scale confidently across web, mobile, and cloud environments.