How do you implement OAuth 2.0 and OpenID Connect?

4 minadvancedsecurityOAuth2OpenID-Connectauthentication

Quick Answer

OAuth 2.0 is an authorization framework that issues access tokens so an app can act on a user's behalf without their credentials; OpenID Connect (OIDC) layers authentication on top, adding an ID token that proves who the user is. In ASP.NET Core you typically configure the OpenID Connect/JWT bearer middleware against an identity provider (Azure AD/Entra, IdentityServer, Auth0), using the authorization-code-with-PKCE flow for interactive apps.

Detailed Answer

OAuth 2.0 provides authorization, while OpenID Connect adds authentication on top of OAuth 2.0.

Implementation in .NET Core:

  1. Install Required Packages:
dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnect
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
  1. Configure Authentication (Startup.cs):
public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(options =>
    {
        options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
    })
    .AddCookie()
    .AddOpenIdConnect(options =>
    {
        options.Authority = "https://your-identity-provider.com";
        options.ClientId = "your-client-id";
        options.ClientSecret = "your-client-secret";
        options.ResponseType = "code";
        options.SaveTokens = true;
        options.GetClaimsFromUserInfoEndpoint = true;
        
        options.Scope.Add("openid");
        options.Scope.Add("profile");
        options.Scope.Add("email");
        
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true
        };
    });
}

public void Configure(IApplicationBuilder app)
{
    app.UseAuthentication();
    app.UseAuthorization();
}
  1. Protecting Endpoints:
[Authorize]
public class SecureController : Controller
{
    public IActionResult Index()
    {
        var userName = User.Identity.Name;
        var claims = User.Claims;
        return View();
    }
}
  1. API Authentication with JWT:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.Authority = "https://your-identity-provider.com";
        options.Audience = "your-api-resource";
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true
        };
    });
  1. Using Identity Server (Self-hosted):
// Install: dotnet add package IdentityServer4
services.AddIdentityServer()
    .AddInMemoryClients(Config.Clients)
    .AddInMemoryApiScopes(Config.ApiScopes)
    .AddInMemoryIdentityResources(Config.IdentityResources)
    .AddDeveloperSigningCredential();
  1. Calling Protected APIs:
public class ApiClient
{
    private readonly HttpClient _httpClient;
    private readonly IHttpContextAccessor _httpContextAccessor;
    
    public async Task GetDataAsync()
    {
        var accessToken = await _httpContextAccessor.HttpContext
            .GetTokenAsync("access_token");
            
        _httpClient.DefaultRequestHeaders.Authorization = 
            new AuthenticationHeaderValue("Bearer", accessToken);
            
        var response = await _httpClient.GetAsync("https://api.example.com/data");
        return await response.Content.ReadAsStringAsync();
    }
}