i have the following problem in my Blazor (.Net 8) App. I Try to use the YARP Map Forwarder (Microsoft.Extensions.ServiceDiscovery.Yarp 8.0.2) to forward requests, that reach Blazor Server from Blazor Client, to a backend service, as a sort of a reverse Proxy. It always returns 502 Bad Gateway. What am i missing here?
...
app.UseRouting();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAntiforgery();
app.UseAuthorization();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof(BlazorProject.Client._Imports).Assembly);
// Always returns 502. As far as i can tell it forwards the request to itself instead of localhost:5000, but i may be wrong here
app.MapForwarder("/weather-forecast", "http://localhost:5000", transformBuilder =>
{
transformBuilder.AddRequestTransform(async transformContext =>
{
var accessToken = await transformContext.HttpContext.GetTokenAsync("access_token");
transformContext.ProxyRequest.Headers.Authorization = new("Bearer", accessToken);
});
}).RequireAuthorization();
I have tried to add new ForwarderRequestConfig { Version = Version.Parse("1.1") }
to the MapForwarder, which yielded no success.
I have also tried to manipulate the ProxyReqeust
via the transformContext
and to set the Route directly or to do Header manipulations but nohting worked.
However custom handling via app.Map
works just fine.
// Custom example
var httpClient = new HttpMessageInvoker(new SocketsHttpHandler
{
UseProxy = false,
AllowAutoRedirect = false,
AutomaticDecompression = DecompressionMethods.None,
UseCookies = false,
EnableMultipleHttp2Connections = true,
ActivityHeadersPropagator = new ReverseProxyPropagator(DistributedContextPropagator.Current),
ConnectTimeout = TimeSpan.FromSeconds(15),
});
// Setup our own request transform class
var transformer = new CustomHttpTransformer();
var requestConfig = new ForwarderRequestConfig { ActivityTimeout = TimeSpan.FromSeconds(10)};
app.Map("/weather-forecast", async (HttpContext httpContext, IHttpForwarder forwarder) =>
{
var error = await forwarder.SendAsync(httpContext, "http://localhost:5000",
httpClient, requestConfig, transformer);
// Check if the operation was successful
if (error != ForwarderError.None)
{
var errorFeature = httpContext.GetForwarderErrorFeature();
throw errorFeature?.Exception ?? new Exception($"ForwarderError: {error}. Getting standard exception failed");
}
}).RequireAuthorization();
// Content of CustomHttpTransformer
public override async ValueTask TransformRequestAsync(HttpContext httpContext,
HttpRequestMessage proxyRequest, string destinationPrefix, CancellationToken cancellationToken)
{
// Copy all request headers
await base.TransformRequestAsync(httpContext, proxyRequest, destinationPrefix, cancellationToken);
// Customize the query string:
var queryContext = new QueryTransformContext(httpContext.Request);
// Set custom uri
proxyRequest.RequestUri = RequestUtilities.MakeDestinationAddress($"{destinationPrefix}", httpContext.Request.Path, queryContext.QueryString);
// Suppress the original request header, use the one from the destination Uri.
proxyRequest.Headers.Host = null;
// Set authorization Headers
var accessToken = await httpContext.GetTokenAsync("access_token");
proxyRequest.Headers.Authorization = new("Bearer", accessToken);
}