C
C#2y ago
Hejle

Certificate Authorization using MinimalAPI

Hi, I have been trying to authorize calls to a localhost service using certificates. Using the certificates, I can then add Clains to the client, that can be used to define what can be accessed and not accessed. This all works, and I can check the claims by accessing User from the HttpContext. However, I would like to use the RequireAuthorization method instead, but when I enable it, it looks like my certificate is never validated.
var builder = WebApplication.CreateBuilder(args);
builder.Logging.AddConsole();
builder.Services.Configure<KestrelServerOptions>(kestrelServerOptions =>
{
kestrelServerOptions.ConfigureHttpsDefaults(httpsConnectionAdapterOptions =>
{
httpsConnectionAdapterOptions.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
httpsConnectionAdapterOptions.AllowAnyClientCertificate();
});
});
builder.Services.AddScoped<ICertificateValidationService, X509CertificateValidationService>();

builder.Services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
.AddCertificate(ValidateCertificateHandlerMethod());
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("HasAccesPolicy", policy =>
policy.RequireClaim("Access", "HasAccess"));
});
var app = builder.Build();
app.UseAuthentication();
app.UseAuthentication();

app.MapGet("/", (ClaimsPrincipal user) => user.Claims.Select(x => new {x.Type, x.Value}));

app.MapGet("/SecureService", (HttpContext context) =>
{
var claims = context.User.Claims;
if (claims.FirstOrDefault(x => x.Type == "Access" && x.Value == "HasAccess") == null)
{
context.Response.StatusCode = 403;
return "";
}
return "Hello from secure service";
}).RequireAuthorization("HasAccesPolicy");
var builder = WebApplication.CreateBuilder(args);
builder.Logging.AddConsole();
builder.Services.Configure<KestrelServerOptions>(kestrelServerOptions =>
{
kestrelServerOptions.ConfigureHttpsDefaults(httpsConnectionAdapterOptions =>
{
httpsConnectionAdapterOptions.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
httpsConnectionAdapterOptions.AllowAnyClientCertificate();
});
});
builder.Services.AddScoped<ICertificateValidationService, X509CertificateValidationService>();

builder.Services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
.AddCertificate(ValidateCertificateHandlerMethod());
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("HasAccesPolicy", policy =>
policy.RequireClaim("Access", "HasAccess"));
});
var app = builder.Build();
app.UseAuthentication();
app.UseAuthentication();

app.MapGet("/", (ClaimsPrincipal user) => user.Claims.Select(x => new {x.Type, x.Value}));

app.MapGet("/SecureService", (HttpContext context) =>
{
var claims = context.User.Claims;
if (claims.FirstOrDefault(x => x.Type == "Access" && x.Value == "HasAccess") == null)
{
context.Response.StatusCode = 403;
return "";
}
return "Hello from secure service";
}).RequireAuthorization("HasAccesPolicy");
So my authentication works when I remove the "RequireAuthorization", but I would rather use that method than getting claims from the httpcontext.
2 Replies
Tvde1
Tvde12y ago
in
options.AddPolicy("HasAccesPolicy", policy =>
policy.RequireClaim("Access", "HasAccess"))
options.AddPolicy("HasAccesPolicy", policy =>
policy.RequireClaim("Access", "HasAccess"))
Try adding policy.AuthenticationMethods.Add(Certificate) not sure what it should be, but something like that add to the policy that certificate auth should be used ah it's
policy.AddAuthenticationSchemes(CertificateAuthenticationDefaults.AuthenticationScheme)
policy.AddAuthenticationSchemes(CertificateAuthenticationDefaults.AuthenticationScheme)
Hejle
HejleOP2y ago
Thank you, it works like a charm!
Want results from more Discord servers?
Add your server