-
Hello, I'm having a difficult time getting Yarp and mTLS working together successfully. I'm building a reverse proxy to front a service that requires mTLS and OAuth 2.0 Client Authentication private_key_jwt method in order to expose it to other internal services that don't have such capabilities. Since I'm using yarp as a forwarder, I'm just using the builder.Services.AddHttpForwarder(); The forwarding code looks like the following: app.Map("/{**catch-all}", async (HttpContext context, IHttpForwarder forwarder, MyHttpTransformer transformer, HttpMessageInvoker httpMessageInvoker) =>
{
var result = await forwarder.SendAsync(context, "https://{downstream-host}", httpMessageInvoker, ForwarderRequestConfig.Empty, transformer);
if (result != ForwarderError.None)
{
// log error
}
}); My custom public class MyHttpTransformer : HttpTransformer
{
public override async ValueTask TransformRequestAsync(HttpContext context, HttpRequestMessage proxyRequest, string destinationPrefix, CancellationToken cancellationToken)
{
await base.TransformRequestAsync(context, proxyRequest, destinationPrefix, cancellationToken);
var apiScopeProvider = context.RequestServices.GetRequiredService<ApiScopeProvider>();
var jwtTokenProvider = context.RequestServices.GetRequiredService<JwtTokenProvider>();
// Get the scope from the current request URI
var scope = apiScopeProvider.GetScope(context.Request);
var token = await jwtTokenProvider.GetJwtTokenAsync(scope);
proxyRequest.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(token.TokenType, token.AccessToken);
}
} and the builder.Services.AddTransient(sp =>
{
return new HttpMessageInvoker(sp.GetRequiredService<ClientCredentialsHttpMessageHandler>());
});
public class ClientCredentialsHttpMessageHandler : HttpClientHandler
{
public ClientCredentialsHttpMessageHandler(MutualTlsClientCertificateProvider clientCertificateProvider)
{
ClientCertificateOptions = ClientCertificateOption.Manual;
ClientCertificates.Add(clientCertificateProvider.GetClientCertificate());
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return base.SendAsync(request, cancellationToken);
}
} When executing a request against my reverse proxy, I hit the following error
I've also tried to use a If I use a simple At this point I tried to look under the hood so I fired up wireshark and realized that there's a difference between using HttpClient: Now I think this may be the root cause of my issue so, but I'm not very well versed in those low level connection details and would gladly appreciate any suggestion/hint. I'm running out of ideas. Thank you |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
I just figured out that the issue was due to the host header not being set in the request so Yarp was copying it from the current request (the one to the yarp service) which was localhost. The fix is at easy as adding: proxyRequest.Headers.Host = new Uri(destinationPrefix).Host; in the |
Beta Was this translation helpful? Give feedback.
I just figured out that the issue was due to the host header not being set in the request so Yarp was copying it from the current request (the one to the yarp service) which was localhost.
The fix is at easy as adding:
in the
MyHttpTransformer
class.