HttpClientHandler
client certificates for downstream services
#1968
Replies: 23 comments 16 replies
-
@AlexKuriatnyk you could do it with delegating handlers docs http://ocelot.readthedocs.io/en/latest/features/delegatinghandlers.html Or maybe just have a piece of middleware before the Ocelot pipeline. Let me know if that helps. |
Beta Was this translation helpful? Give feedback.
-
Looks like it is not possible to do this just with delegating handlers. I need to setup client certificate on HttpClientHandler that is used for HttpClient. |
Beta Was this translation helpful? Give feedback.
-
@AlexKuriatnyk this should be possible to implement in Ocelot. How do you set the certificate on the HttpClientHandler? If should just be a case of getting the certificate into Ocelot somehow and then passing it through to the HttpClientBuilder to HttpClientHandler. How does the certificate get passed to the downstream service? Is this like part of the TCP/IP handshake or as a header or something? If it is a header then we might have other options. |
Beta Was this translation helpful? Give feedback.
-
I set it in this way: httpclientHandler.ClientCertificates.Add(certificate);. I believe, it is passed as part of the TCP/IP. I my case, I read it by Subject from certificate storage on machine. |
Beta Was this translation helpful? Give feedback.
-
@AlexKuriatnyk ok cool I will take a look at it ASAP! |
Beta Was this translation helpful? Give feedback.
-
Hello! I have a similar scenario. How I can deal with it? |
Beta Was this translation helpful? Give feedback.
-
Any update on this one? I have a similar issue where I can't reach my downstream host returning "The remote certificate is invalid according to the validation procedure". I have a self-signed cert, by the way.
certificate.json
|
Beta Was this translation helpful? Give feedback.
-
Hi. I have created two branches that targets this issue. First: This way user will be able to change client certs and proxy settings. Could you provide your thoughts about this? |
Beta Was this translation helpful? Give feedback.
-
We tried to adjust
However, the target API is still not getting the client certificate. The issue might be with the fact that the client certificate from Certificate on the target API side is read in the following way.
Any thought how client certificate can be convey to the target API? In addition, is there any particular reason to directly create an instance of |
Beta Was this translation helpful? Give feedback.
-
temporary workaround: class X509Hanlder: DelegatingHandler
{
private CertificateRepository _certificateRepository;
public X509Hanlder(CertificateRepository certificateRepository)
{
_certificateRepository = certificateRepository;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
var inner = this.InnerHandler;
while(inner is DelegatingHandler) {
inner = ((DelegatingHandler)inner).InnerHandler;
}
// inner is HttpClientHandler
if(inner is HttpClientHandler)
{
var httpClientHandler = (HttpClientHandler) inner;
if(httpClientHandler.ClientCertificateOptions != ClientCertificateOption.Automatic)
{
await AddCerificates(httpClientHandler, request);
}
}
return await base.SendAsync(request, cancellationToken);
}
private async Task AddCerificates(HttpClientHandler httpClientHandler, HttpRequestMessage request)
{
X509CertificateCollection ceritificates = await this._certificateRepository.GetAllAsync();
httpClientHandler.ClientCertificates.AddRange(ceritificates);
httpClientHandler.ClientCertificateOptions = ClientCertificateOption.Automatic;
}
} |
Beta Was this translation helpful? Give feedback.
-
Hi, EDIT: As all I wanted to do was ensure downstream services could only be accessed through an API gateway, I have instead changed the approach to have ocelot add a header with a hash to be verified by the downstream service. The presence of a valid hash will suffice for now. I am trying to get downstream certificates to work. I simply want to add a certificate to the request received by ocelot and have the downstream service verify the certificate. I have registered a DelegatingHandler with almost the same code as presented by @g00fy. I see the call to the SendAsync method adding the certificate to httpClientHandler.ClientCertificates. The downstream service is called without issue, but the certificate is not present. i.e. HttpContext.Connection.ClientCertificate returns a null value. I have created a certificate for secure.local and added imported it into Cert:\LocalMachine\Root Calls to https://secure.local:12000/U/V1/Testing is setup to reroute to https://secure.local:12010/V1/Testing. This is working, only as mentioned, the certificate added to the request is not being received by the downstream service. Is there something I am missing? powershell - used to create self-cert
ocelot.json
Delegating Handler
Kind regards, |
Beta Was this translation helpful? Give feedback.
-
Any update on this issue? |
Beta Was this translation helpful? Give feedback.
-
Has there been any status update on this issue? I'm in a similar situation where I want to forward the certificate but no approach so far has worked |
Beta Was this translation helpful? Give feedback.
-
@AlexKuriatnyk Hello Alex!
Could you describe your user scenarios in details please?
Answer: I believe Yes, because ASP.NET provides this feature, but Ocelot not. Why do you need Ocelot's machine certificates in downstream? |
Beta Was this translation helpful? Give feedback.
-
Hello, Has there been any update regarding this. Thanks. |
Beta Was this translation helpful? Give feedback.
-
We are patient but still wait for your contributions. @ggnaegi Seems we need to redesign system core... |
Beta Was this translation helpful? Give feedback.
-
@raman-m, setting |
Beta Was this translation helpful? Give feedback.
-
@nikhillkumar @raman-m you still have an option, it's adding your own logic here: RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
{
... your validation logic here
} or even better (would help us with a PR) public interface ICertificateValidator
{
bool Validate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors);
}
services.AddSingleton<ICertificateValidator, CustomCertificateValidator>(); |
Beta Was this translation helpful? Give feedback.
-
@ggnaegi, thank you so much for pointing in this direction. |
Beta Was this translation helpful? Give feedback.
-
Sorry, which PR are you talking about? Anyway, we are not going to rewrite our generic validator which covers all validation scenarios of all self-signed certificates because it simply returns We will not accept and approve any PRs with changes of this line! Moreover it will be removed in future! 👉 The quote from docs:
@ggnaegi FYI ! |
Beta Was this translation helpful? Give feedback.
-
@raman-m Yes, I just gave a solution to @nikhillkumar, but the feature should be implemented imo. |
Beta Was this translation helpful? Give feedback.
-
I think we should first convert this to a discussion and talk about the approach we would like to take. It's an important feature, that is not implemented "out of the box" in other projects (for the known reverse proxies, you will need to compile your own library too). |
Beta Was this translation helpful? Give feedback.
-
@raman-m @nikhillkumar Are we mixing concerns here? I realized that the topic was about downstream service authentication using certificates. and, correct me if I'm wrong, @nikhillkumar you are more interested by certificate validation, yes? So, we might have two distincts topics here: 1) Authentication with Certificates, 2) Custom certificates validation. |
Beta Was this translation helpful? Give feedback.
-
Hello,
We have a scenario when some services behind the gateway require certificate-based authentication. Is it possible to add client certificate to the downstream call somehow?
Beta Was this translation helpful? Give feedback.
All reactions