Skip to content

Commit 7037831

Browse files
authored
Expose VaultSharp's PostProcessHttpClientHandlerAction hook (#52)
Expose PostProcessHttpClientHandlerAction via the VaultSharp configuration provider settings. This allows arbitrary customizations to the underlying HTTP client, such as customizing HTTP proxy settings.
1 parent ec06b46 commit 7037831

File tree

3 files changed

+66
-0
lines changed

3 files changed

+66
-0
lines changed

Source/VaultSharp.Extensions.Configuration/VaultConfigurationProvider.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ public override void Load()
9292
{
9393
clientHandler.ServerCertificateCustomValidationCallback = this.ConfigurationSource.Options.ServerCertificateCustomValidationCallback;
9494
}
95+
96+
this.ConfigurationSource.Options.PostProcessHttpClientHandlerAction?.Invoke(clientHandler);
9597
}
9698
}
9799
};

Source/VaultSharp.Extensions.Configuration/VaultOptions.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,5 +163,17 @@ public VaultOptions(
163163
/// An optional action to post-process the HttpClientHandler. Used to manually validate the server certificate. Ignored if AcceptInsecureConnection is true.
164164
/// </summary>
165165
public Func<HttpRequestMessage, X509Certificate2?, X509Chain?, SslPolicyErrors, bool>? ServerCertificateCustomValidationCallback { get; set;}
166+
167+
/// <summary>
168+
/// An optional hook to allow custom configuration of the HttpClientHandler.
169+
/// This is useful if you need to customize the HTTP client's proxy settings, for example.
170+
/// </summary>
171+
/// <remarks>
172+
/// The action will be invoked after the VaultSharp provider applies the AcceptInsecureConnection and ServerCertificateCustomValidationCallback
173+
/// customizations, if you enabled them. Be aware that if you overwrite the HttpMessageHandler's ServerCertificateCustomValidationCallback
174+
/// in your action-handler method, you will cancel out the effect of enabling the AcceptInsecureConnection and/or
175+
/// ServerCertificateCustomValidationCallback options.
176+
/// </remarks>
177+
public Action<HttpMessageHandler>? PostProcessHttpClientHandlerAction { get; set; }
166178
}
167179
}

Tests/VaultSharp.Extensions.Configuration.Test/IntegrationTests.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,58 @@ public async Task Failure_PermissionDenied()
616616
It.Is<Func<It.IsAnyType, Exception?, string>>((v, t) => true)), Times.Once);
617617

618618
}
619+
620+
[Fact]
621+
public async Task Success_Proxy_Verify_Custom_Hook_Invoked()
622+
{
623+
// arrange
624+
using CancellationTokenSource cts = new CancellationTokenSource();
625+
var values =
626+
new Dictionary<string, IEnumerable<KeyValuePair<string, object>>>
627+
{
628+
{
629+
"myservice-config", new[]
630+
{
631+
new KeyValuePair<string, object>("option1", "value1"),
632+
new KeyValuePair<string, object>("subsection", new {option2 = "value2"}),
633+
}
634+
},
635+
};
636+
637+
var container = this.PrepareVaultContainer();
638+
try
639+
{
640+
await container.StartAsync(cts.Token).ConfigureAwait(false);
641+
await this.LoadDataAsync("http://localhost:8200", values).ConfigureAwait(false);
642+
643+
// Moq mock of PostProcessHttpClientHandlerAction implementation:
644+
var mockConfigureProxyAction = new Mock<Action<HttpMessageHandler>>();
645+
646+
// act
647+
ConfigurationBuilder builder = new ConfigurationBuilder();
648+
builder.AddVaultConfiguration(
649+
() => new VaultOptions("http://localhost:8200", new TokenAuthMethodInfo("root"), reloadOnChange: true, reloadCheckIntervalSeconds: 10, omitVaultKeyName: true)
650+
{
651+
PostProcessHttpClientHandlerAction = mockConfigureProxyAction.Object
652+
},
653+
"myservice-config",
654+
"secret",
655+
this.logger);
656+
var configurationRoot = builder.Build();
657+
658+
// assert secrets were loaded successfully:
659+
configurationRoot.GetValue<string>("option1").Should().Be("value1");
660+
configurationRoot.GetSection("subsection").GetValue<string>("option2").Should().Be("value2");
661+
662+
// assert that PostProcessHttpClientHandlerAction was actually invoked, and a HttpMessageHandler was passed:
663+
mockConfigureProxyAction.Verify(x => x(It.IsAny<HttpMessageHandler>()), Times.Once);
664+
}
665+
finally
666+
{
667+
cts.Cancel();
668+
await container.DisposeAsync().ConfigureAwait(false);
669+
}
670+
}
619671
}
620672

621673
public class TestConfigObject

0 commit comments

Comments
 (0)