Skip to content
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

feat: retrieve client cert from header #770

Merged
merged 5 commits into from
May 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 11 additions & 12 deletions sample/terraform/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,16 @@ locals {
}
# enable wave on config change
deploymentAnnotations = local.deploymentAnnotations

# ingress annotations
ingress = {
annotations = {
"kubernetes.io/ingress.class" = "nginx"
"cert-manager.io/cluster-issuer" = "letsencrypt"
"nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream" = "true"
"nginx.ingress.kubernetes.io/auth-tls-verify-client" = "off"
}
}
appSettings = {
file = {
# override certificate authentication options
Expand All @@ -111,6 +121,7 @@ locals {
IdentityServerOptions = {
MutualTls = {
Enabled = true
PEMHeader = "ssl-client-cert"
}
EnableServerSideSession = true
ServerSideSessions = {
Expand Down Expand Up @@ -233,18 +244,6 @@ resource "helm_release" "nginx_ingress" {
name = "controller.extraArgs.enable-ssl-passthrough"
value = true
}

# Specify that certificates are to be passed on
set {
name = "nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream"
value = true
}

# Don't request client certificates and don't do client certificate verification
set {
name = "nginx.ingress.kubernetes.io/auth-tls-verify-client"
value = "off"
}

wait = local.wait
}
Expand Down
3 changes: 2 additions & 1 deletion src/Aguacongas.TheIdServer.Duende/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
},
"IdentityServerOptions": {
"MutualTls": {
"Enabled": true
"Enabled": true,
"PEMHeader": "ssl-client-cert"
},
"EnableServerSideSession": true,
"ServerSideSessions": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
using Aguacongas.TheIdServer.Options.OpenTelemetry;
#if DUENDE
using Duende.IdentityServer.Hosting;
using Duende.IdentityServer.Configuration;
#else
using IdentityServer4.Configuration;
#endif
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
Expand All @@ -28,16 +31,19 @@
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
using Serilog;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using System;

namespace Microsoft.AspNetCore.Builder
{
Expand Down Expand Up @@ -118,6 +124,17 @@ public static IApplicationBuilder UseTheIdServer(this IApplicationBuilder app, I
})
.UseRouting();

app.Use((context, next) =>
{
var certificateHeader = configuration.GetValue<string>($"{nameof(IdentityServerOptions)}:{nameof(IdentityServerOptions.MutualTls)}:PEMHeader");
if (!string.IsNullOrEmpty(certificateHeader) &&
context.Request.Headers.TryGetValue(certificateHeader, out StringValues values))
{
context.Connection.ClientCertificate = X509Certificate2.CreateFromPem(Uri.UnescapeDataString(values.First()));
}
return next();
});

#if DUENDE
app.UseMiddleware<BaseUrlMiddleware>()
.ConfigureCors();
Expand All @@ -132,7 +149,7 @@ public static IApplicationBuilder UseTheIdServer(this IApplicationBuilder app, I

if (!isProxy)
{
app.UseIdentityServerAdminAuthentication(" /providerhub", JwtBearerDefaults.AuthenticationScheme);
app.UseIdentityServerAdminAuthentication("/providerhub", JwtBearerDefaults.AuthenticationScheme);
}

app.UseAuthorization()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@
<None Update="test.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="test.pem">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@
}
},
"IdentityServerOptions": {
"MutualTls": {
"Enabled": true,
"PEMHeader": "ssl-client-cert"
},
"EnableServerSideSession": true,
"ServerSideSessions": {
"UserDisplayNameClaimType": "name",
"ExpiredSessionsTriggerBackchannelLogout": true
"ExpiredSessionsTriggerBackchannelLogout": true
},
"Endpoints": {
"EnableJwtRequestUri": false
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-----BEGIN CERTIFICATE-----
MIIBwTCCAUegAwIBAgIQXaDIvEoqig0+NPNA+RC3fTAKBggqhkjOPQQDAzAiMSAw
HgYDVQQDExdjZXJ0LW1hbmFnZXItd2ViaG9vay1jYTAeFw0yMjA0MDQxMzA0MDda
Fw0yMzA0MDQxMzA0MDdaMCIxIDAeBgNVBAMTF2NlcnQtbWFuYWdlci13ZWJob29r
LWNhMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAED92pPSkT9GsE2/d2UWFookvzA8cV
Wu0lcsnXywm3zp1b9XVjCVOYsDi/LbQEektmF0LfmVLrPQr/UOnVRuDo0yYGZ2/d
NuQLvbh1kIHaPEOCCsWnVi85W6C79VH6W56eo0IwQDAOBgNVHQ8BAf8EBAMCAqQw
DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUR6pr0tyvFI+9/YbAniHgPmXAuIsw
CgYIKoZIzj0EAwMDaAAwZQIwKWHhHqqDNg9hyZLpKfKQpwK8WRzUfmwDjgeT2mbw
l6r6WVq+k6Qgrewtqg3MB5ytAjEA/ESZ5hiXWE1iP8YnxwKJTrh2CXxEKm+f6VMD
Rt9roAyFSvK2KUmsqLH5C0gPUNwL
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@
<None Update="test.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="test.pem">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
}
},
"IdentityServerOptions": {
"MutualTls": {
"Enabled": true,
"PEMHeader": "ssl-client-cert"
},
"Endpoints": {
"EnableJwtRequestUri": true
}
Expand Down
12 changes: 12 additions & 0 deletions test/IS4/Aguacongas.TheIdServer.Integration.IS4.Test/test.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-----BEGIN CERTIFICATE-----
MIIBwTCCAUegAwIBAgIQXaDIvEoqig0+NPNA+RC3fTAKBggqhkjOPQQDAzAiMSAw
HgYDVQQDExdjZXJ0LW1hbmFnZXItd2ViaG9vay1jYTAeFw0yMjA0MDQxMzA0MDda
Fw0yMzA0MDQxMzA0MDdaMCIxIDAeBgNVBAMTF2NlcnQtbWFuYWdlci13ZWJob29r
LWNhMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAED92pPSkT9GsE2/d2UWFookvzA8cV
Wu0lcsnXywm3zp1b9XVjCVOYsDi/LbQEektmF0LfmVLrPQr/UOnVRuDo0yYGZ2/d
NuQLvbh1kIHaPEOCCsWnVi85W6C79VH6W56eo0IwQDAOBgNVHQ8BAf8EBAMCAqQw
DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUR6pr0tyvFI+9/YbAniHgPmXAuIsw
CgYIKoZIzj0EAwMDaAAwZQIwKWHhHqqDNg9hyZLpKfKQpwK8WRzUfmwDjgeT2mbw
l6r6WVq+k6Qgrewtqg3MB5ytAjEA/ESZ5hiXWE1iP8YnxwKJTrh2CXxEKm+f6VMD
Rt9roAyFSvK2KUmsqLH5C0gPUNwL
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,26 @@
using Microsoft.Extensions.Primitives;
using Aguacongas.IdentityServer.Abstractions;
using Microsoft.AspNetCore.Identity;
using Aguacongas.TheIdServer.IntegrationTest.BlazorApp;
using System.Net.Http;
using System.Net;

namespace Aguacongas.TheIdServer.IntegrationTest
{
public class ServiceCollectionExtensionsTest
{
[Fact]
public async Task Configure_should_add_get_certificate_from_header_middleware()
{
using var factory = new TheIdServerFactory();
using var client = factory.CreateClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "/connect");
request.Headers.Add("ssl-client-cert", Uri.EscapeDataString(File.ReadAllText("test.pem")));
using var response = await client.SendAsync(request).ConfigureAwait(false);

Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}

[Fact]
public async Task SeedData_should_seed_data()
{
Expand Down