问题
I am working with Flurl to hit an API that requires certificate-based authentication. I have seen from this SO post that adding a certificate to a WebRequestHandler
and instructing an HttpClient
to use this handler is easy.
However, it is not so clear for me using Flurl. I have tried the follwing three things.
Extending DefaultHttpFactory
I first suspected that I needed to create my own X509HttpFactory : DefaultHttpFactory
which would create the handler and assign it to the HttpClient
. However, in viewing the source, I notice that the constructor for CreateClient
already expects a handler. Where does this handler come from?
Creating Client using DefaultHttpFactory
WebRequestHandler handler = new WebRequestHandler();
handler.ClientCertificates.Add(myX509Cert);
var clientFactory = new DefaultHttpClientFactory();
FlurlClient fc = clientFactory.CreateClient(url, handler);
This does not compile as HttpClient
cannot be casted to FlurlClient
Use ConfigureHttpClient
var clientFactory = new DefaultHttpClientFactory();
FlurlClient fc = new Url("foobar.com").ConfigureHttpClient(client => client = clientFactory
.CreateClient(url, handler));
This seems like the most viable option, but I'm unsure since the delegate is an Action
with no return type.
The Question
What is the best/correct way to support client-side certificate authentication using Flurl?
回答1:
You're close - a custom factory is definitely the way to go. But you want to override CreateMessageHandler
rather than CreateClient
:
public class X509HttpFactory : DefaultHttpClientFactory
{
private readonly X509Certificate2 _cert;
public X509HttpFactory(X509Certificate2 cert) {
_cert = cert;
}
public override HttpMessageHandler CreateMessageHandler() {
var handler = new WebRequestHandler();
handler.ClientCertificates.Add(_cert);
return handler;
}
}
Then you can either register it globally (on app startup):
FlurlHttp.Configure(settings => {
settings.HttpClientFactory = new X509HttpFactory(myCert);
});
Or for all calls to a particular host:
FlurlHttp.ConfigureClient(ROOT_URL, cli => {
cli.Settings.HttpClientFactory = new X509HttpFactory(myCert);
});
Or for a new FlurlClient
:
var cli = new FlurlClient(url)
.Configure(settings => settings.HttpClientFactory = new X509HttpFactory(myCert));
Or an existing one:
cli.Settings.HttpClientFactory = new X509HttpFactory(myCert);
来源:https://stackoverflow.com/questions/41033337/c-sharp-flurl-add-webrequesthandler-to-flurlclient