从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
相关产品推荐
相关产品推荐

