Add WithProxy(string proxyUrl, X509Certificate2 certificate) (#880)

This commit is contained in:
Stef Heyenrath
2023-02-01 10:42:35 +01:00
committed by GitHub
parent 1000f4409f
commit 6839b11d35
6 changed files with 93 additions and 56 deletions

View File

@@ -35,9 +35,14 @@ internal static class HttpClientBuilder
{
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
var x509Certificate2 = CertificateLoader.LoadCertificate(settings.ClientX509Certificate2ThumbprintOrSubjectName);
var x509Certificate2 = CertificateLoader.LoadCertificate(settings.ClientX509Certificate2ThumbprintOrSubjectName!);
handler.ClientCertificates.Add(x509Certificate2);
}
else if (settings.Certificate != null)
{
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.ClientCertificates.Add(settings.Certificate);
}
handler.AllowAutoRedirect = settings.AllowAutoRedirect == true;

View File

@@ -1,4 +1,4 @@
using JetBrains.Annotations;
using System.Security.Cryptography.X509Certificates;
using WireMock.Settings;
namespace WireMock.ResponseBuilders;
@@ -17,9 +17,17 @@ public interface IProxyResponseBuilder : IStatusCodeResponseBuilder
IResponseBuilder WithProxy(string proxyUrl, string? clientX509Certificate2ThumbprintOrSubjectName = null);
/// <summary>
/// WithProxy using IProxyAndRecordSettings.
/// WithProxy using <see cref="ProxyAndRecordSettings"/>.
/// </summary>
/// <param name="settings">The IProxyAndRecordSettings.</param>
/// <param name="settings">The ProxyAndRecordSettings.</param>
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithProxy([NotNull] ProxyAndRecordSettings settings);
IResponseBuilder WithProxy(ProxyAndRecordSettings settings);
/// <summary>
/// WithProxy using <see cref="X509Certificate2"/>.
/// </summary>
/// <param name="proxyUrl">The proxy url.</param>
/// <param name="certificate"">The X509Certificate2.</param>
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithProxy(string proxyUrl, X509Certificate2 certificate);
}

View File

@@ -2,6 +2,7 @@ using System.Net.Http;
using WireMock.Http;
using WireMock.Settings;
using Stef.Validation;
using System.Security.Cryptography.X509Certificates;
namespace WireMock.ResponseBuilders;
@@ -38,4 +39,19 @@ public partial class Response
_httpClientForProxy = HttpClientBuilder.Build(settings);
return this;
}
/// <inheritdoc />
public IResponseBuilder WithProxy(string proxyUrl, X509Certificate2 certificate)
{
Guard.NotNullOrEmpty(proxyUrl);
Guard.NotNull(certificate);
var settings = new ProxyAndRecordSettings
{
Url = proxyUrl,
Certificate = certificate
};
return WithProxy(settings);
}
}

View File

@@ -1,9 +1,11 @@
using System.Security.Cryptography.X509Certificates;
namespace WireMock.Settings;
/// <summary>
/// HttpClientSettings
/// </summary>
public class HttpClientSettings
public abstract class HttpClientSettings
{
/// <summary>
/// The clientCertificate thumbprint or subject name fragment to use.
@@ -20,4 +22,9 @@ public class HttpClientSettings
/// Proxy requests should follow redirection (30x).
/// </summary>
public bool? AllowAutoRedirect { get; set; }
/// <summary>
/// The <see cref="X509Certificate2"/> to use.
/// </summary>
public X509Certificate2? Certificate { get; set; }
}

View File

@@ -1,54 +1,53 @@
using JetBrains.Annotations;
namespace WireMock.Settings
namespace WireMock.Settings;
/// <summary>
/// If https is used, these settings can be used to configure the CertificateSettings in case a custom certificate instead the default .NET certificate should be used.
///
/// X509StoreName and X509StoreLocation should be defined
/// OR
/// X509CertificateFilePath and X509CertificatePassword should be defined
/// </summary>
public class WireMockCertificateSettings
{
/// <summary>
/// If https is used, these settings can be used to configure the CertificateSettings in case a custom certificate instead the default .NET certificate should be used.
///
/// X509 StoreName (AddressBook, AuthRoot, CertificateAuthority, My, Root, TrustedPeople or TrustedPublisher)
/// </summary>
[PublicAPI]
public string? X509StoreName { get; set; }
/// <summary>
/// X509 StoreLocation (CurrentUser or LocalMachine)
/// </summary>
[PublicAPI]
public string? X509StoreLocation { get; set; }
/// <summary>
/// X509 Thumbprint or SubjectName (if not defined, the 'host' is used)
/// </summary>
[PublicAPI]
public string? X509StoreThumbprintOrSubjectName { get; set; }
/// <summary>
/// X509Certificate FilePath
/// </summary>
[PublicAPI]
public string? X509CertificateFilePath { get; set; }
/// <summary>
/// X509Certificate Password
/// </summary>
[PublicAPI]
public string? X509CertificatePassword { get; set; }
/// <summary>
/// X509StoreName and X509StoreLocation should be defined
/// OR
/// X509CertificateFilePath and X509CertificatePassword should be defined
/// </summary>
public class WireMockCertificateSettings
{
/// <summary>
/// X509 StoreName (AddressBook, AuthRoot, CertificateAuthority, My, Root, TrustedPeople or TrustedPublisher)
/// </summary>
[PublicAPI]
public string? X509StoreName { get; set; }
/// <summary>
/// X509 StoreLocation (CurrentUser or LocalMachine)
/// </summary>
[PublicAPI]
public string? X509StoreLocation { get; set; }
/// <summary>
/// X509 Thumbprint or SubjectName (if not defined, the 'host' is used)
/// </summary>
[PublicAPI]
public string? X509StoreThumbprintOrSubjectName { get; set; }
/// <summary>
/// X509Certificate FilePath
/// </summary>
[PublicAPI]
public string? X509CertificateFilePath { get; set; }
/// <summary>
/// X509Certificate Password
/// </summary>
[PublicAPI]
public string? X509CertificatePassword { get; set; }
/// <summary>
/// X509StoreName and X509StoreLocation should be defined
/// OR
/// X509CertificateFilePath and X509CertificatePassword should be defined
/// </summary>
[PublicAPI]
public bool IsDefined =>
!string.IsNullOrEmpty(X509StoreName) && !string.IsNullOrEmpty(X509StoreLocation) ||
!string.IsNullOrEmpty(X509CertificateFilePath);
}
[PublicAPI]
public bool IsDefined =>
!string.IsNullOrEmpty(X509StoreName) && !string.IsNullOrEmpty(X509StoreLocation) ||
!string.IsNullOrEmpty(X509CertificateFilePath);
}

View File

@@ -1,6 +1,3 @@
using FluentAssertions;
using Moq;
using NFluent;
using System;
using System.Linq;
using System.Net;
@@ -8,6 +5,9 @@ using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using FluentAssertions;
using Moq;
using NFluent;
using WireMock.Constants;
using WireMock.Handlers;
using WireMock.Matchers;
@@ -144,9 +144,11 @@ public class WireMockServerProxyTests
};
var server = WireMockServer.Start(settings);
server.Given(Request.Create()
server
.Given(Request.Create()
.WithPath("/*")
.WithBody(new RegexMatcher(stringBody)))
.WithBody(new RegexMatcher(stringBody))
)
.WithTitle(title)
.WithDescription(description)
.AtPriority(WireMockConstants.ProxyPriority)