JWT, OAuth, OpenID Connect, and Azure AD: Authentication Levels

Introduction

In modern web applications, ensuring secure and efficient authentication is paramount. Several protocols and standards exist to address different aspects of authentication and authorization. This blog will delve into JWT (JSON Web Tokens), OAuth, OpenID Connect, and Azure AD, exploring why they are necessary and how they fit together in the authentication landscape. We'll also provide C# examples to illustrate their usage.

  • JWT (JSON Web Tokens): A compact, URL-safe means of representing claims to be transferred between two parties. It is often used for securely transmitting information between parties as a JSON object.
  • OAuth (Open Authorization): An open standard for access delegation, commonly used as a way to grant websites or applications limited access to user information without exposing passwords.
  • OpenID Connect (OIDC): An identity layer built on top of OAuth 2.0, enabling clients to verify the identity of the end-user and obtain basic profile information.
  • Azure AD (Azure Active Directory): A cloud-based identity and access management service by Microsoft, providing single sign-on and multi-factor authentication to help protect users from cybersecurity attacks.

Each of these technologies addresses different aspects of authentication and authorization. Let's explore them step by step.

1. JWT (JSON Web Tokens)

JWT is a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed.

Why is JWT Needed?

JWTs are widely used for authentication because they can be used to verify the identity of users and securely transmit claims between parties. They are also useful in stateless authentication mechanisms.

How does JWT work?

  1. Header: Contains information about how the token is generated.
  2. Payload: Contains the claims. This is the information you want to transmit.
  3. Signature: Ensures that the token wasn't changed along the way.

Generating a JWT

using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using Microsoft.IdentityModel.Tokens;
using System.Text;

public string GenerateJwtToken(string userId)
{
    var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("YourSecretKey"));
    var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

    var claims = new[]
    {
        new Claim(JwtRegisteredClaimNames.Sub, userId),
        new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
    };

    var token = new JwtSecurityToken(
        issuer: "yourdomain.com",
        audience: "yourdomain.com",
        claims: claims,
        expires: DateTime.Now.AddMinutes(30),
        signingCredentials: credentials);

    return new JwtSecurityTokenHandler().WriteToken(token);
}

Validating a JWT

public ClaimsPrincipal ValidateJwtToken(string token)
{
    var tokenHandler = new JwtSecurityTokenHandler();
    var key = Encoding.ASCII.GetBytes("YourSecretKey");

    var validationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = "yourdomain.com",
        ValidAudience = "yourdomain.com",
        IssuerSigningKey = new SymmetricSecurityKey(key)
    };

    return tokenHandler.ValidateToken(token, validationParameters, out _);
}

2. OAuth (Open Authorization)

OAuth is an open standard for access delegation, commonly used to grant websites or applications limited access to user information without exposing passwords.

Why is OAuth Needed?

OAuth allows users to grant third-party applications access to their resources without sharing their credentials. This improves security and user experience.

How does OAuth Work?

  1. Authorization: The user is asked to authorize the application to access their resources.
  2. Token Exchange: An authorization code is exchanged for an access token.
  3. Access: The access token is used to access the user's resources.

OAuth Authorization Code Flow

// Redirect the user to the authorization endpoint
public IActionResult Authorize()
{
    var redirectUrl = Url.Action("Callback", "Home", null, Request.Scheme);
    var properties = new AuthenticationProperties { RedirectUri = redirectUrl };
    return Challenge(properties, "OAuthProvider");
}

// Handle the callback from the authorization server
public async Task<IActionResult> Callback()
{
    var authenticateResult = await HttpContext.AuthenticateAsync("ExternalCookie");

    if (!authenticateResult.Succeeded)
        return BadRequest(); // Handle error

    // Exchange the authorization code for an access token
    var tokenResponse = await HttpContext.GetTokenAsync("access_token");

    return Ok(tokenResponse);
}

3. OpenID Connect (OIDC)

OpenID Connect is an identity layer on top of OAuth 2.0, providing a way to verify the identity of the end-user based on the authentication performed by an authorization server.

Why is OpenID Connect Needed?

OIDC adds an identity layer to OAuth, allowing clients to verify the identity of the end-user and obtain basic profile information, which is essential for authentication.

How Does OpenID Connect Work?

  1. Authentication Request: The client requests authentication from the authorization server.
  2. Authentication Response: The authorization server authenticates the user and returns an ID token along with the access token.
  3. User Info: The client can request additional user information.

Using OpenID Connect Middleware

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
    options.ClientId = "client_id";
    options.ClientSecret = "client_secret";
    options.Authority = "https://your-identity-server";
    options.ResponseType = "code";
    options.SaveTokens = true;
});

4. Azure AD (Azure Active Directory)

Azure AD is a cloud-based identity and access management service by Microsoft, providing single sign-on, multi-factor authentication, and conditional access to protect users from cybersecurity attacks.

Why is Azure AD Needed?

Azure AD simplifies the management of users and groups, providing robust security features like conditional access and multi-factor authentication, making it a powerful tool for enterprise identity management.

How does Azure AD Work?

  1. User Authentication: Users authenticate using Azure AD credentials.
  2. Token Issuance: Azure AD issues tokens for access to resources.
  3. Token Validation: Applications validate the tokens to grant access.

Integrating Azure AD

services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
    .AddAzureAD(options => Configuration.Bind("AzureAd", options));

Token Validation

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.Authority = $"https://login.microsoftonline.com/{tenantId}/v2.0";
            options.Audience = clientId;
        });
}

Conclusion

  1. JWT: Provides a compact and secure way to transmit claims between parties.
  2. OAuth: Grants limited access to user resources without exposing credentials.
  3. OpenID Connect: Adds an identity layer on top of OAuth for user authentication.
  4. Azure AD: Manages identities and access in the cloud, providing robust security features.

These technologies can be used individually or together, depending on your application's requirements. Understanding how they work and how to implement them ensures that your application remains secure and efficient.