-
Notifications
You must be signed in to change notification settings - Fork 273
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #162 from DuendeSoftware/joe/mtls-net8
Update mTLS to .NET 8
- Loading branch information
Showing
131 changed files
with
327 additions
and
198 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
{ | ||
"version": "0.2.0", | ||
"compounds": [ | ||
{ | ||
"name": "Run All", | ||
"configurations": ["IdentityServerHost", "Api", "ClientCredentials"], | ||
"presentation": { | ||
"group": "10-compunds", | ||
} | ||
} | ||
], | ||
"configurations": [ | ||
{ | ||
"name": "IdentityServerHost", | ||
"type": "coreclr", | ||
"request": "launch", | ||
"preLaunchTask": "build-identityserverhost", | ||
"program": "${workspaceFolder}/IdentityServerHost/bin/Debug/net8.0/IdentityServerHost.dll", | ||
"args": [], | ||
"cwd": "${workspaceFolder}/IdentityServerHost", | ||
"env": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
}, | ||
"console": "externalTerminal", | ||
}, | ||
{ | ||
"name": "Api", | ||
"type": "coreclr", | ||
"request": "launch", | ||
"preLaunchTask": "build-api", | ||
"program": "${workspaceFolder}/Api/bin/Debug/net8.0/Api.dll", | ||
"args": [], | ||
"cwd": "${workspaceFolder}/Api/", | ||
"env": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
}, | ||
"console": "externalTerminal", | ||
}, | ||
{ | ||
"name": "ClientCredentials", | ||
"type": "coreclr", | ||
"request": "launch", | ||
"preLaunchTask": "build-clientcredentials", | ||
"program": "${workspaceFolder}/ClientCredentials/bin/Debug/net8.0/ClientCredentials.dll", | ||
"args": [], | ||
"cwd": "${workspaceFolder}/ClientCredentials", | ||
"console": "externalTerminal", | ||
"env": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
}, | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
{ | ||
"version": "2.0.0", | ||
"tasks": [ | ||
{ | ||
"label": "build", | ||
"type": "process", | ||
"command": "dotnet", | ||
"args": [ | ||
"build", | ||
"${workspaceFolder}/MTLS.sln", | ||
"/property:GenerateFullPaths=true", | ||
"/consoleloggerparameters:NoSummary" | ||
], | ||
"problemMatcher": "$msCompile" | ||
}, | ||
{ | ||
"label": "build-identityserverhost", | ||
"type": "process", | ||
"command": "dotnet", | ||
"args": [ | ||
"build", | ||
"${workspaceFolder}/IdentityServerHost", | ||
"/property:GenerateFullPaths=true", | ||
"/consoleloggerparameters:NoSummary" | ||
], | ||
"problemMatcher": "$msCompile" | ||
}, | ||
{ | ||
"label": "build-api", | ||
"type": "process", | ||
"command": "dotnet", | ||
"args": [ | ||
"build", | ||
"${workspaceFolder}/Api", | ||
"/property:GenerateFullPaths=true", | ||
"/consoleloggerparameters:NoSummary" | ||
], | ||
"problemMatcher": "$msCompile" | ||
}, | ||
{ | ||
"label": "build-clientcredentials", | ||
"type": "process", | ||
"command": "dotnet", | ||
"args": [ | ||
"build", | ||
"${workspaceFolder}/ClientCredentials", | ||
"/property:GenerateFullPaths=true", | ||
"/consoleloggerparameters:NoSummary" | ||
], | ||
"problemMatcher": "$msCompile" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,12 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net6.0</TargetFramework> | ||
<TargetFramework>net8.0</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" /> | ||
|
||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.0" /> | ||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.1" /> | ||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.0" /> | ||
</ItemGroup> | ||
|
||
</Project> |
86 changes: 42 additions & 44 deletions
86
IdentityServer/v7/MTLS/Api/ConfirmationValidationMiddleware.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,68 +1,66 @@ | ||
using Microsoft.AspNetCore.Authentication; | ||
using Microsoft.AspNetCore.Http; | ||
using Newtonsoft.Json.Linq; | ||
using System; | ||
using System.Security.Cryptography; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Authentication.JwtBearer; | ||
using Microsoft.AspNetCore.Builder; | ||
using Microsoft.Extensions.Logging; | ||
using System.Text.Json; | ||
|
||
namespace SampleApi | ||
namespace Api; | ||
|
||
public static class ConfirmationValidationExtensions | ||
{ | ||
public static class ConfirmationValidationExtensions | ||
public static IApplicationBuilder UseConfirmationValidation(this IApplicationBuilder app, ConfirmationValidationMiddlewareOptions options = default) | ||
{ | ||
public static IApplicationBuilder UseConfirmationValidation(this IApplicationBuilder app, ConfirmationValidationMiddlewareOptions options = default) | ||
{ | ||
return app.UseMiddleware<ConfirmationValidationMiddleware>(options ?? new ConfirmationValidationMiddlewareOptions()); | ||
} | ||
return app.UseMiddleware<ConfirmationValidationMiddleware>(options ?? new ConfirmationValidationMiddlewareOptions()); | ||
} | ||
} | ||
|
||
public class ConfirmationValidationMiddlewareOptions | ||
{ | ||
public string JwtBearerSchemeName { get; set; } = JwtBearerDefaults.AuthenticationScheme; | ||
} | ||
|
||
public class ConfirmationValidationMiddlewareOptions | ||
// this middleware validate the cnf claim (if present) against the thumbprint of the X.509 client certificate for the current client | ||
public class ConfirmationValidationMiddleware | ||
{ | ||
private readonly RequestDelegate _next; | ||
private readonly ILogger _logger; | ||
private readonly ConfirmationValidationMiddlewareOptions _options; | ||
|
||
public ConfirmationValidationMiddleware(RequestDelegate next, ILogger<ConfirmationValidationMiddlewareOptions> logger, ConfirmationValidationMiddlewareOptions options = null) | ||
{ | ||
public string JwtBearerSchemeName { get; set; } = JwtBearerDefaults.AuthenticationScheme; | ||
_next = next; | ||
_logger = logger; | ||
_options ??= new ConfirmationValidationMiddlewareOptions(); | ||
} | ||
|
||
// this middleware validate the cnf claim (if present) against the thumbprint of the X.509 client certificate for the current client | ||
public class ConfirmationValidationMiddleware | ||
{ | ||
private readonly RequestDelegate _next; | ||
private readonly ILogger _logger; | ||
private readonly ConfirmationValidationMiddlewareOptions _options; | ||
|
||
public ConfirmationValidationMiddleware(RequestDelegate next, ILogger<ConfirmationValidationMiddlewareOptions> logger, ConfirmationValidationMiddlewareOptions options = null) | ||
{ | ||
_next = next; | ||
_logger = logger; | ||
_options ??= new ConfirmationValidationMiddlewareOptions(); | ||
} | ||
|
||
public async Task Invoke(HttpContext ctx) | ||
public async Task Invoke(HttpContext ctx) | ||
{ | ||
if (ctx.User.Identity.IsAuthenticated) | ||
{ | ||
if (ctx.User.Identity.IsAuthenticated) | ||
var cnfJson = ctx.User.FindFirst("cnf")?.Value; | ||
if (!String.IsNullOrWhiteSpace(cnfJson)) | ||
{ | ||
var cnfJson = ctx.User.FindFirst("cnf")?.Value; | ||
if (!String.IsNullOrWhiteSpace(cnfJson)) | ||
{ | ||
var certificate = await ctx.Connection.GetClientCertificateAsync(); | ||
var thumbprint = Base64UrlTextEncoder.Encode(certificate.GetCertHash(HashAlgorithmName.SHA256)); | ||
|
||
var cnf = JObject.Parse(cnfJson); | ||
var sha256 = cnf.Value<string>("x5t#S256"); | ||
var certificate = await ctx.Connection.GetClientCertificateAsync(); | ||
var thumbprint = Base64UrlTextEncoder.Encode(certificate.GetCertHash(HashAlgorithmName.SHA256)); | ||
|
||
if (String.IsNullOrWhiteSpace(sha256) || | ||
!thumbprint.Equals(sha256, StringComparison.OrdinalIgnoreCase)) | ||
{ | ||
_logger.LogError("certificate thumbprint does not match cnf claim."); | ||
await ctx.ChallengeAsync(_options.JwtBearerSchemeName); | ||
return; | ||
} | ||
|
||
_logger.LogDebug("certificate thumbprint matches cnf claim."); | ||
var sha256 = JsonDocument.Parse(cnfJson).RootElement.GetString("x5t#S256"); | ||
|
||
if (String.IsNullOrWhiteSpace(sha256) || | ||
!thumbprint.Equals(sha256, StringComparison.OrdinalIgnoreCase)) | ||
{ | ||
_logger.LogError("certificate thumbprint does not match cnf claim."); | ||
await ctx.ChallengeAsync(_options.JwtBearerSchemeName); | ||
return; | ||
} | ||
|
||
_logger.LogDebug("certificate thumbprint matches cnf claim."); | ||
} | ||
|
||
await _next(ctx); | ||
} | ||
|
||
await _next(ctx); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,36 @@ | ||
using System; | ||
using Microsoft.AspNetCore; | ||
using Microsoft.AspNetCore.Hosting; | ||
using Microsoft.Extensions.Hosting; | ||
using Serilog; | ||
using Serilog.Events; | ||
using Serilog.Sinks.SystemConsole.Themes; | ||
|
||
namespace SampleApi | ||
namespace Api; | ||
|
||
public class Program | ||
{ | ||
public class Program | ||
public static void Main(string[] args) | ||
{ | ||
public static void Main(string[] args) | ||
{ | ||
Console.Title = "Sample API"; | ||
Console.Title = "API"; | ||
|
||
BuildWebHost(args).Run(); | ||
} | ||
BuildWebHost(args).Run(); | ||
} | ||
|
||
public static IWebHost BuildWebHost(string[] args) | ||
{ | ||
Log.Logger = new LoggerConfiguration() | ||
.MinimumLevel.Verbose() | ||
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning) | ||
.MinimumLevel.Override("System", LogEventLevel.Warning) | ||
.MinimumLevel.Override("Microsoft.AspNetCore.Authentication", LogEventLevel.Information) | ||
.Enrich.FromLogContext() | ||
.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}", theme: AnsiConsoleTheme.Code) | ||
.CreateLogger(); | ||
public static IHost BuildWebHost(string[] args) | ||
{ | ||
Log.Logger = new LoggerConfiguration() | ||
.MinimumLevel.Information() | ||
.Enrich.FromLogContext() | ||
.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}", theme: AnsiConsoleTheme.Code) | ||
.CreateLogger(); | ||
|
||
return WebHost.CreateDefaultBuilder(args) | ||
.UseStartup<Startup>() | ||
.UseSerilog() | ||
.Build(); | ||
} | ||
return Host.CreateDefaultBuilder(args) | ||
.ConfigureWebHostDefaults(webBuilder => | ||
{ | ||
webBuilder.UseStartup<Startup>(); | ||
}) | ||
.UseSerilog() | ||
.Build(); | ||
} | ||
} |
Oops, something went wrong.