mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-04-22 08:18:26 +02:00
Add client certificate support (#862)
* Add client certificate support * Add missing test certificate file * Review fixes * Review fixes * Review fixes * Review fixes
This commit is contained in:
@@ -2,9 +2,10 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Https;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using WireMock.HttpsCertificate;
|
||||
using CertificateLoader = WireMock.HttpsCertificate.CertificateLoader;
|
||||
|
||||
namespace WireMock.Owin
|
||||
{
|
||||
@@ -26,21 +27,25 @@ namespace WireMock.Owin
|
||||
{
|
||||
kestrelOptions.ListenAnyIP(urlDetail.Port, listenOptions =>
|
||||
{
|
||||
if (wireMockMiddlewareOptions.CustomCertificateDefined)
|
||||
listenOptions.UseHttps(options =>
|
||||
{
|
||||
listenOptions.UseHttps(CertificateLoader.LoadCertificate(
|
||||
wireMockMiddlewareOptions.X509StoreName,
|
||||
wireMockMiddlewareOptions.X509StoreLocation,
|
||||
wireMockMiddlewareOptions.X509ThumbprintOrSubjectName,
|
||||
wireMockMiddlewareOptions.X509CertificateFilePath,
|
||||
wireMockMiddlewareOptions.X509CertificatePassword,
|
||||
urlDetail.Host)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
listenOptions.UseHttps();
|
||||
}
|
||||
if (wireMockMiddlewareOptions.CustomCertificateDefined)
|
||||
{
|
||||
options.ServerCertificate = CertificateLoader.LoadCertificate(
|
||||
wireMockMiddlewareOptions.X509StoreName,
|
||||
wireMockMiddlewareOptions.X509StoreLocation,
|
||||
wireMockMiddlewareOptions.X509ThumbprintOrSubjectName,
|
||||
wireMockMiddlewareOptions.X509CertificateFilePath,
|
||||
wireMockMiddlewareOptions.X509CertificatePassword,
|
||||
urlDetail.Host);
|
||||
}
|
||||
|
||||
options.ClientCertificateMode = (ClientCertificateMode) wireMockMiddlewareOptions.ClientCertificateMode;
|
||||
if (wireMockMiddlewareOptions.AcceptAnyClientCertificate)
|
||||
{
|
||||
options.ClientCertificateValidation = (_, _, _) => true;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
else
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Server.Kestrel;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Https;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using WireMock.HttpsCertificate;
|
||||
@@ -23,21 +24,22 @@ internal partial class AspNetCoreSelfHost
|
||||
{
|
||||
if (urlDetail.IsHttps)
|
||||
{
|
||||
if (wireMockMiddlewareOptions.CustomCertificateDefined)
|
||||
options.UseHttps(new HttpsConnectionFilterOptions
|
||||
{
|
||||
options.UseHttps(CertificateLoader.LoadCertificate(
|
||||
wireMockMiddlewareOptions.X509StoreName,
|
||||
wireMockMiddlewareOptions.X509StoreLocation,
|
||||
wireMockMiddlewareOptions.X509ThumbprintOrSubjectName,
|
||||
wireMockMiddlewareOptions.X509CertificateFilePath,
|
||||
wireMockMiddlewareOptions.X509CertificatePassword,
|
||||
urlDetail.Host)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
options.UseHttps(PublicCertificateHelper.GetX509Certificate2());
|
||||
}
|
||||
ServerCertificate = wireMockMiddlewareOptions.CustomCertificateDefined
|
||||
? CertificateLoader.LoadCertificate(
|
||||
wireMockMiddlewareOptions.X509StoreName,
|
||||
wireMockMiddlewareOptions.X509StoreLocation,
|
||||
wireMockMiddlewareOptions.X509ThumbprintOrSubjectName,
|
||||
wireMockMiddlewareOptions.X509CertificateFilePath,
|
||||
wireMockMiddlewareOptions.X509CertificatePassword,
|
||||
urlDetail.Host)
|
||||
: PublicCertificateHelper.GetX509Certificate2(),
|
||||
ClientCertificateMode = (ClientCertificateMode) wireMockMiddlewareOptions.ClientCertificateMode,
|
||||
ClientCertificateValidation = wireMockMiddlewareOptions.AcceptAnyClientCertificate
|
||||
? (_, _, _) => true
|
||||
: null,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,10 @@ internal interface IWireMockMiddlewareOptions
|
||||
Action<IServiceCollection>? AdditionalServiceRegistration { get; set; }
|
||||
|
||||
CorsPolicyOptions? CorsPolicyOptions { get; set; }
|
||||
|
||||
ClientCertificateMode ClientCertificateMode { get; set; }
|
||||
|
||||
bool AcceptAnyClientCertificate { get; set; }
|
||||
#endif
|
||||
|
||||
IFileSystemHandler? FileSystemHandler { get; set; }
|
||||
|
||||
@@ -68,7 +68,21 @@ namespace WireMock.Owin.Mappers
|
||||
body = await BodyParser.ParseAsync(bodyParserSettings).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return new RequestMessage(options, urlDetails, method, clientIP, body, headers, cookies) { DateTime = DateTime.UtcNow };
|
||||
return new RequestMessage(
|
||||
options,
|
||||
urlDetails,
|
||||
method,
|
||||
clientIP,
|
||||
body,
|
||||
headers,
|
||||
cookies
|
||||
#if USE_ASPNETCORE
|
||||
, await request.HttpContext.Connection.GetClientCertificateAsync()
|
||||
#endif
|
||||
)
|
||||
{
|
||||
DateTime = DateTime.UtcNow
|
||||
};
|
||||
}
|
||||
|
||||
private static (UrlDetails UrlDetails, string ClientIP) ParseRequest(IRequest request)
|
||||
|
||||
@@ -42,6 +42,11 @@ internal class WireMockMiddlewareOptions : IWireMockMiddlewareOptions
|
||||
public Action<IServiceCollection>? AdditionalServiceRegistration { get; set; }
|
||||
|
||||
public CorsPolicyOptions? CorsPolicyOptions { get; set; }
|
||||
|
||||
public ClientCertificateMode ClientCertificateMode { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool AcceptAnyClientCertificate { get; set; }
|
||||
#endif
|
||||
|
||||
/// <inheritdoc cref="IWireMockMiddlewareOptions.FileSystemHandler"/>
|
||||
|
||||
@@ -4,6 +4,9 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
#if USE_ASPNETCORE
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
#endif
|
||||
using Stef.Validation;
|
||||
using WireMock.Models;
|
||||
using WireMock.Owin;
|
||||
@@ -92,6 +95,11 @@ public class RequestMessage : IRequestMessage
|
||||
/// <inheritdoc cref="IRequestMessage.Origin" />
|
||||
public string Origin { get; }
|
||||
|
||||
#if USE_ASPNETCORE
|
||||
/// <inheritdoc cref="IRequestMessage.ClientCertificate" />
|
||||
public X509Certificate2? ClientCertificate { get; }
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Used for Unit Testing
|
||||
/// </summary>
|
||||
@@ -115,13 +123,20 @@ public class RequestMessage : IRequestMessage
|
||||
/// <param name="bodyData">The BodyData.</param>
|
||||
/// <param name="headers">The headers.</param>
|
||||
/// <param name="cookies">The cookies.</param>
|
||||
#if USE_ASPNETCORE
|
||||
/// <param name="clientCertificate">The client certificate</param>
|
||||
#endif
|
||||
internal RequestMessage(
|
||||
IWireMockMiddlewareOptions? options,
|
||||
UrlDetails urlDetails, string method,
|
||||
string clientIP,
|
||||
IBodyData? bodyData = null,
|
||||
IDictionary<string, string[]>? headers = null,
|
||||
IDictionary<string, string>? cookies = null)
|
||||
IDictionary<string, string>? cookies = null
|
||||
#if USE_ASPNETCORE
|
||||
, X509Certificate2? clientCertificate = null
|
||||
#endif
|
||||
)
|
||||
{
|
||||
Guard.NotNull(urlDetails, nameof(urlDetails));
|
||||
Guard.NotNull(method, nameof(method));
|
||||
@@ -156,6 +171,9 @@ public class RequestMessage : IRequestMessage
|
||||
Cookies = cookies;
|
||||
RawQuery = urlDetails.Url.Query;
|
||||
Query = QueryStringParser.Parse(RawQuery, options?.QueryParameterMultipleValueSupport);
|
||||
#if USE_ASPNETCORE
|
||||
ClientCertificate = clientCertificate;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -226,7 +226,9 @@ public partial class WireMockServer
|
||||
QueryParameterMultipleValueSupport = _settings.QueryParameterMultipleValueSupport,
|
||||
|
||||
#if USE_ASPNETCORE
|
||||
CorsPolicyOptions = _settings.CorsPolicyOptions?.ToString()
|
||||
CorsPolicyOptions = _settings.CorsPolicyOptions?.ToString(),
|
||||
ClientCertificateMode = _settings.ClientCertificateMode,
|
||||
AcceptAnyClientCertificate = _settings.AcceptAnyClientCertificate
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -275,6 +277,9 @@ public partial class WireMockServer
|
||||
_settings.CorsPolicyOptions = corsPolicyOptions;
|
||||
_options.CorsPolicyOptions = corsPolicyOptions;
|
||||
}
|
||||
|
||||
_options.ClientCertificateMode = _settings.ClientCertificateMode;
|
||||
_options.AcceptAnyClientCertificate = _settings.AcceptAnyClientCertificate;
|
||||
#endif
|
||||
|
||||
return ResponseMessageBuilder.Create("Settings updated");
|
||||
|
||||
@@ -331,6 +331,8 @@ public partial class WireMockServer : IWireMockServer
|
||||
#if USE_ASPNETCORE
|
||||
_options.AdditionalServiceRegistration = _settings.AdditionalServiceRegistration;
|
||||
_options.CorsPolicyOptions = _settings.CorsPolicyOptions;
|
||||
_options.ClientCertificateMode = _settings.ClientCertificateMode;
|
||||
_options.AcceptAnyClientCertificate = _settings.AcceptAnyClientCertificate;
|
||||
|
||||
_httpServer = new AspNetCoreSelfHost(_options, urlOptions);
|
||||
#else
|
||||
|
||||
@@ -235,6 +235,19 @@ public class WireMockServerSettings
|
||||
[PublicAPI]
|
||||
public bool CustomCertificateDefined => CertificateSettings?.IsDefined == true;
|
||||
|
||||
#if USE_ASPNETCORE
|
||||
/// <summary>
|
||||
/// Client certificate mode for the server
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public ClientCertificateMode ClientCertificateMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to accept any client certificate
|
||||
/// </summary>
|
||||
public bool AcceptAnyClientCertificate { get; set; }
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Defines the global IWebhookSettings to use.
|
||||
/// </summary>
|
||||
|
||||
@@ -64,6 +64,8 @@ public static class WireMockServerSettingsParser
|
||||
|
||||
#if USE_ASPNETCORE
|
||||
settings.CorsPolicyOptions = parser.GetEnumValue(nameof(WireMockServerSettings.CorsPolicyOptions), CorsPolicyOptions.None);
|
||||
settings.ClientCertificateMode = parser.GetEnumValue(nameof(WireMockServerSettings.ClientCertificateMode), ClientCertificateMode.NoCertificate);
|
||||
settings.AcceptAnyClientCertificate = parser.GetBoolValue(nameof(WireMockServerSettings.AcceptAnyClientCertificate));
|
||||
#endif
|
||||
|
||||
var loggerType = parser.GetStringValue("WireMockLogger");
|
||||
|
||||
Reference in New Issue
Block a user