This guide shows how to validate mTLS certificate-bound access tokens in a .NET API using the MonoCloud API Authentication .NET SDK.
mTLS certificate binding ensures that an access token can only be used by the client that holds the corresponding TLS certificate.
This guide assumes you've completed the installation guide.
You should already have:
MonoCloud.Authentication.Api SDK installedMonoCloud section configured in appsettings.jsonConfigure Kestrel to request client certificates during the TLS handshake, then enable certificate binding validation.
using MonoCloud.Authentication.Api;
using Microsoft.AspNetCore.Server.Kestrel.Https;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(kestrel =>
{
kestrel.ConfigureHttpsDefaults(https =>
{
https.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
https.ClientCertificateValidation = (_, _, _) => true;
});
});
builder.Services
.AddAuthentication(MonoCloudAuthenticationDefaults.AuthenticationScheme)
.AddMonoCloudAuthentication(options =>
{
options.TenantDomain = builder.Configuration["MonoCloud:TenantDomain"];
options.Audience = builder.Configuration["MonoCloud:Audience"];
options.ValidateCertificateBinding = _ => true;
});
builder.Services.AddAuthorization();
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapGet("/api/data", () => "Protected data")
.RequireAuthorization();
app.Run();
How it works:
ClientCertificateMode.AllowCertificate tells Kestrel to request a client certificate during the TLS handshakeClientCertificateValidation returns true so the application handles binding validation instead of rejecting the request at the TLS layerValidateCertificateBinding = _ => true verifies that the token's cnf.x5t#S256 claim matches the SHA-256 thumbprint of the presented client certificate| Scenario | Status code | Response |
|---|---|---|
| Missing or invalid token | 401 | Unauthorized |
| Token not bound to a certificate | 401 | Unauthorized |
| Certificate thumbprint mismatch | 401 | Unauthorized |
| Valid token with matching certificate | — | Endpoint handler executes |