Overview

edit

Meziantou.AspNetCore.Authentication.HttpBasic is an authentication handler for HTTP Basic: the client sends a username and a password in the Authorization header of every request, and the handler turns them into a ClaimsPrincipal.

dotnet package add Meziantou.AspNetCore.Authentication.HttpBasic

The types are in the Meziantou.AspNetCore.Authentication.HttpBasic namespace.

Warning

HTTP Basic sends the password on every request, encoded with Base64, which is not encryption. Serve these endpoints over HTTPS only. A leaked Basic credential is the password itself, and it can be replayed until the password changes.

Protect an endpoint

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddAuthentication(HttpBasicAuthenticationDefaults.AuthenticationScheme)
    .AddHttpBasic(options =>
    {
        options.Realm = "My application";
        options.MaxCredentialLength = 4096;
        options.ValidateCredentials = (context, username, password) =>
        {
            if (!string.Equals(username, "admin", StringComparison.Ordinal) ||
                !string.Equals(password, "secret", StringComparison.Ordinal))
            {
                return ValueTask.FromResult<ClaimsPrincipal?>(null);
            }

            var claims = new[]
            {
                new Claim(ClaimTypes.Name, username),
                new Claim(ClaimTypes.NameIdentifier, username),
            };
            var identity = new ClaimsIdentity(claims, authenticationType: HttpBasicAuthenticationDefaults.AuthenticationScheme);
            return ValueTask.FromResult<ClaimsPrincipal?>(new ClaimsPrincipal(identity));
        };
    });

builder.Services.AddAuthorization();

var app = builder.Build();

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

app.MapGet("/", (ClaimsPrincipal user) => $"Hello {user.Identity?.Name}!")
    .RequireAuthorization();

app.Run();

A request without credentials, or with wrong ones, gets 401 Unauthorized with a WWW-Authenticate: Basic realm="My application", charset="UTF-8" header, so a browser shows its sign-in prompt.

Two ways to validate credentials

When to use HTTP Basic

HTTP Basic fits clients that cannot run an interactive sign-in: scripts, build agents, monitoring probes, devices, or a private feed consumed by a package manager. For users in a browser, a cookie-based sign-in is safer: the password is sent once instead of on every request.

Before exposing an endpoint, read Securing a Basic endpoint: rate limiting, account lockout and the limits of the handler.