You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用YARP简单转发功能时,如何自动添加X-Forwarded请求头?

YARP简单转发场景下自动添加X-Forwarded请求头的最佳方案

我正在使用YARP的IHttpForwarder将请求反向代理到上游服务,仅需替换传入请求的主机名和部分路径后转发。但由于没有使用完整的反向代理中间件(比如UseReverseProxy()),无法直接使用内置的X-Forwarded请求头自动添加功能。当前示例代码如下:

ForwarderRequestConfig requestOptions = new(){ ActivityTimeout = TimeSpan.FromSeconds(100) };

app.UseRouting();

app.Map(
    "/test/{**catch-all}",
    async (HttpContext httpContext, IHttpForwarder forwarder) =>
{
    var error = await forwarder.SendAsync(
        httpContext,
        "http://localhost:5001",
        httpClient,
        requestOptions,
        static (context, proxyRequest) =>
        {
            var queryContext = new QueryTransformContext(context.Request);

            var transformedPath = context.Request.Path;

            if (transformedPath.StartsWithSegments("/test", remaining: out var remaining))
            {
                transformedPath = remaining;
            }

            proxyRequest.RequestUri = RequestUtilities.MakeDestinationAddress(
                "http://localhost:5001",
                transformedPath,
                queryContext.QueryString);

            proxyRequest.Headers.Host = null;

            return default;
        });


    if (error != ForwarderError.None)
    {
        var errorFeature = httpContext.Features.Get<IForwarderErrorFeature>();
        var exception = errorFeature.Exception;

        // TODO
    }
});

我希望能通过类似request.AddXForwarded();的扩展方法,让YARP自动添加正确的X-Forwarded系列请求头并完成必要验证,而不是手动编写头信息。请问使用YARP实现此需求的最佳方案是什么?


解决方案

YARP内置了专门处理X-Forwarded头的工具类ForwardedHeadersUtilities,可以直接在请求转换委托中调用其方法来实现自动添加与验证,无需手动拼接头信息。

1. 引入必要命名空间

确保代码顶部添加:

using Yarp.ReverseProxy.Forwarder;

2. 修改请求转换逻辑

在请求转换的委托中,调用ForwardedHeadersUtilities.AddXForwardedHeaders方法,该方法会自动处理X-Forwarded-For、X-Forwarded-Proto、X-Forwarded-Host等标准头,同时完成重复头处理、IP验证等逻辑。

修改后的完整代码示例:

using Yarp.ReverseProxy.Forwarder;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpForwarder();
builder.Services.AddHttpClient();

var app = builder.Build();

ForwarderRequestConfig requestOptions = new() { ActivityTimeout = TimeSpan.FromSeconds(100) };

app.UseRouting();

app.Map(
    "/test/{**catch-all}",
    async (HttpContext httpContext, IHttpForwarder forwarder, IHttpClientFactory httpClientFactory) =>
    {
        var httpClient = httpClientFactory.CreateClient();
        var error = await forwarder.SendAsync(
            httpContext,
            "http://localhost:5001",
            httpClient,
            requestOptions,
            static (context, proxyRequest) =>
            {
                var queryContext = new QueryTransformContext(context.Request);

                var transformedPath = context.Request.Path;
                if (transformedPath.StartsWithSegments("/test", remaining: out var remaining))
                {
                    transformedPath = remaining;
                }

                proxyRequest.RequestUri = RequestUtilities.MakeDestinationAddress(
                    "http://localhost:5001",
                    transformedPath,
                    queryContext.QueryString);

                proxyRequest.Headers.Host = null;

                // 调用YARP内置方法自动添加X-Forwarded系列请求头
                ForwardedHeadersUtilities.AddXForwardedHeaders(context, proxyRequest);

                return default;
            });

        if (error != ForwarderError.None)
        {
            var errorFeature = httpContext.Features.Get<IForwarderErrorFeature>();
            var exception = errorFeature?.Exception;
            // 示例错误处理
            httpContext.Response.StatusCode = StatusCodes.Status502BadGateway;
            await httpContext.Response.WriteAsync($"Proxy error: {exception?.Message ?? "Unknown error"}");
        }
    });

app.Run();

3. 自定义配置(可选)

如果需要调整头的生成规则(比如修改头名称、限制允许的代理IP),可以使用重载方法传入ForwardedHeadersOptions参数:

var forwardedOptions = new ForwardedHeadersOptions
{
    ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.All,
    // 添加信任的代理IP,避免伪造的X-Forwarded头
    KnownProxies = { IPAddress.Parse("192.168.1.100") }
};

ForwardedHeadersUtilities.AddXForwardedHeaders(context, proxyRequest, forwardedOptions);

内容的提问来源于stack exchange,提问作者Rob L

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 07:20:03