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

从ASP.NET增量迁移至ASP.NET Core,部署后YARP代理失效

ASP.NET到ASP.NET Core增量迁移中IIS部署下YARP代理重定向问题

问题场景

本地Visual Studio环境中,YARP能正常代理请求到ASP.NET应用,但部署到IIS后,请求会被直接重定向到ASP.NET应用的真实URL,而非通过代理转发。已在IIS中部署ASP.NET和ASP.NET Core两个应用,并将appsettings.json中的目标地址替换为ASP.NET应用的IIS访问URL。

相关代码

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSystemWebAdapters()
       .AddJsonSessionSerializer(options =>
           {
               options.RegisterKey<string>("userInfo");
           })
       .AddRemoteAppClient(option =>
           {
               option.RemoteAppUrl = new(builder.Configuration["ReverseProxy:Clusters:cluster1:Destinations:destination1:Address"]);
               option.ApiKey = builder.Configuration["RemoteAppApiKey"];
           })
       .AddSessionClient();

builder.Services.AddHttpForwarder();
builder.Services.AddControllersWithViews();
var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseSystemWebAdapters();
app.MapDefaultControllerRoute().RequireSystemWebAdapterSession(); 

app.MapForwarder("/{**catch-all}", builder.Configuration["ReverseProxy:Clusters:cluster1:Destinations:destination1:Address"]).Add(static builder => ((RouteEndpointBuilder)builder).Order = int.MaxValue);

app.MapControllerRoute("Default", "{controller=Login}/{action=QLogin}/{id?}").RequireSystemWebAdapterSession();

app.Run();

应用配置

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "RemoteAppApiKey": "cf3ef610-24eb-4d2f-a8f3-1ba4d2dcb87d",
  "AllowedHosts": "*",
  "ReverseProxy": {
    "Routes": {
      "route1": {
        "ClusterId": "cluster1",
        "Match": {
          "Path": "{**catch-all}"
        }
      }
    },
    "Clusters": {
      "cluster1": {
        "Destinations": {
          "destination1": {
            "Address": "http://localhost:62541"
          }
        }
      }
    }
  }
}

解决方案

1. 修正原ASP.NET应用的重定向逻辑

原ASP.NET应用如果用Request.Url生成重定向地址,会直接指向自身真实URL,得改成读取YARP转发的X-Forwarded-*头来构建外部访问地址:

var forwardedProto = Request.Headers["X-Forwarded-Proto"].FirstOrDefault() ?? Request.Url.Scheme;
var forwardedHost = Request.Headers["X-Forwarded-Host"].FirstOrDefault() ?? Request.Url.Host;
var forwardedPort = Request.Headers["X-Forwarded-Port"].FirstOrDefault() ?? Request.Url.Port.ToString();
var externalUrl = new UriBuilder(forwardedProto, forwardedHost, int.Parse(forwardedPort), Request.Url.PathAndQuery).Uri;
// 重定向时使用externalUrl,比如Response.Redirect(externalUrl.ToString());

2. 配置YARP转发时添加正确的转发头

在注册HttpForwarder时,添加转换逻辑设置转发头,让后端ASP.NET应用识别真实请求地址:

builder.Services.AddHttpForwarder(options =>
{
    options.AddTransforms(context =>
    {
        context.ProxyRequest.Headers.TryAdd("X-Forwarded-Proto", context.HttpContext.Request.Protocol);
        context.ProxyRequest.Headers.TryAdd("X-Forwarded-Host", context.HttpContext.Request.Host.ToString());
        var port = context.HttpContext.Request.Host.Port.ToString() ?? (context.HttpContext.Request.IsHttps ? "443" : "80");
        context.ProxyRequest.Headers.TryAdd("X-Forwarded-Port", port);
    });
});

3. 调整IIS站点配置

  • 确保ASP.NET Core应用的IIS站点绑定和用户访问的外部地址一致,比如绑定正确的域名、端口(HTTPS的话要配证书)。
  • 两个应用的应用程序池要分开:ASP.NET Core用.NET Core托管模式,ASP.NET用.NET Framework模式,避免冲突。
  • 可选:限制ASP.NET应用的IIS站点只能被本地访问,防止用户直接访问真实地址。

4. 统一YARP路由配置

当前代码同时用了MapForwarder和配置文件路由,容易冲突。建议移除代码中的app.MapForwarder行,完全依赖appsettings.json中的YARP配置,确保路由优先级正确。

5. 检查HTTPS重定向配置

如果生产环境用HTTPS:

  • 确保ASP.NET Core应用的UseHttpsRedirection配置正确,指定对应HTTPS端口:
    app.UseHttpsRedirection(options =>
    {
        options.HttpsPort = 443; // 实际HTTPS端口
    });
    
  • 后端ASP.NET应用的HTTPS重定向逻辑也要同步使用X-Forwarded-Proto头判断协议,避免强制跳转到自身的HTTP/HTTPS地址。

内容的提问来源于stack exchange,提问作者Nikhil Alex

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 14:14:52