-
Notifications
You must be signed in to change notification settings - Fork 475
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add certificate allow list configuration #5172
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -564,6 +564,27 @@ private static void ConfigureAuthentication(WebApplicationBuilder builder, Dashb | |
{ | ||
OnCertificateValidated = context => | ||
{ | ||
var options = context.HttpContext.RequestServices.GetRequiredService<IOptions<DashboardOptions>>().Value; | ||
if (options.Otlp.AllowedCertificates is { Count: > 0 } allowList) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For my knowledge, why do we need our own custom option? Doesn't Kestrel have an existing setting for which certs are valid? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Kestrel and ASP.NET Core cert auth provides settings for allowing or rejecting invalid certs. However, just because a cert is valid doesn't necessarily mean that it should be allowed to be authenticated. https://learn.microsoft.com/en-us/aspnet/core/security/authentication/certauth?view=aspnetcore-8.0 - see
This PR adds configuration and code for that check. |
||
{ | ||
var allowed = false; | ||
foreach (var rule in allowList) | ||
{ | ||
// Thumbprint is hexadecimal and is case-insensitive. | ||
if (string.Equals(rule.Thumbprint, context.ClientCertificate.Thumbprint, StringComparison.OrdinalIgnoreCase)) | ||
{ | ||
allowed = true; | ||
break; | ||
} | ||
} | ||
|
||
if (!allowed) | ||
{ | ||
context.Fail("Certificate doesn't match allow list."); | ||
return Task.CompletedTask; | ||
} | ||
} | ||
|
||
var claims = new[] | ||
{ | ||
new Claim(ClaimTypes.NameIdentifier, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,8 +43,24 @@ public async Task Configuration_NoExtraConfig_Error() | |
|
||
// Assert | ||
Assert.Collection(app.ValidationFailures, | ||
s => s.Contains("Dashboard:Frontend:EndpointUrls"), | ||
s => s.Contains("Dashboard:Otlp:EndpointUrl")); | ||
s => Assert.Contains("ASPNETCORE_URLS", s), | ||
s => Assert.Contains("DOTNET_DASHBOARD_OTLP_ENDPOINT_URL", s)); | ||
Comment on lines
+46
to
+47
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unrelated, but I noticed this test is wrong when adding the allow certs test. |
||
} | ||
|
||
[Fact] | ||
public async Task Configuration_EmptyAllowedCertificateRule_Error() | ||
{ | ||
// Arrange & Act | ||
await using var app = IntegrationTestHelpers.CreateDashboardWebApplication(testOutputHelper, | ||
additionalConfiguration: data => | ||
{ | ||
data["Dashboard:Otlp:AuthMode"] = nameof(OtlpAuthMode.ClientCertificate); | ||
data["Dashboard:Otlp:AllowedCertificates:0"] = string.Empty; | ||
}); | ||
|
||
// Assert | ||
Assert.Collection(app.ValidationFailures, | ||
s => Assert.Contains("Dashboard:Otlp:AllowedCertificates:0:Thumbprint", s)); | ||
} | ||
|
||
[Fact] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering why this is nullable. Why would we want an instance of this with a null thumbprint?
If the system was configured with a single rule having a null thumbprint, I don't think any connection would ever be accepted.
X509Certificate2.Thumbprint doens't seem to be nullable either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The property is set by configuration so it could be left out and be null. In that case it has no impact because it will never match a cert.
But I will add some validation logic for letting the person launching the dashboard that they're made a mistake.
In case you're wondering why there is
AllowedCertificateRule
rather than a string list of thumbprints, it leaves open the option for extra options when allowing certificates, e.g. allow certs based on issuer.