使用Microsoft.AspNetCore.SystemWebAdapters迁移时遇YARP目标前缀无效错误
问题:使用SystemWebAdapters迁移ASP.NET MVC到Core时YARP触发"Invalid destination prefix"错误
背景
我们正尝试使用Microsoft.AspNetCore.SystemWebAdapters将现有ASP.NET MVC站点增量迁移至ASP.NET Core MVC站点,遵循微软官方指南及示例项目操作后,遇到YARP协议方法触发的错误,该方法由SystemWebAdapters中的以下代码调用:
public Task InvokeAsync(HttpContext context) => context.GetEndpoint()?.Metadata.GetMetadata() is { IsDisabled: false } ? SetUserAsync(context) : _next(context);
异常信息
抛出的异常:
ArgumentException: Invalid destination prefix. (Parameter 'destinationPrefix')
异常调用栈
Yarp.ReverseProxy.Forwarder.HttpForwarder.CreateRequestMessageAsync(HttpContext context, string destinationPrefix, HttpTransformer transformer, ForwarderRequestConfig requestConfig, bool isStreamingRequest, ActivityCancellationTokenSource activityToken) Yarp.ReverseProxy.Forwarder.HttpForwarder.SendAsync(HttpContext context, string destinationPrefix, HttpMessageInvoker httpClient, ForwarderRequestConfig requestConfig, HttpTransformer transformer) Yarp.ReverseProxy.Forwarder.ForwarderMiddleware.Invoke(HttpContext context) Yarp.ReverseProxy.Health.PassiveHealthCheckMiddleware.Invoke(HttpContext context) Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
代码示例
ASP.NET Core站点 Program.cs(未启用SSL)
using System.Security.Claims; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.SystemWebAdapters; var builder = WebApplication.CreateBuilder(args); builder.Services.AddReverseProxy().LoadFromConfig(builder.Configuration.GetSection("ReverseProxy")); // These must match the data protection settings in MvcApp Startup.Auth.cs for cookie sharing to work var sharedApplicationName = "CCM"; builder.Services.AddDataProtection() .PersistKeysToFileSystem(new DirectoryInfo(Path.Combine(Path.GetTempPath(), "sharedkeys", sharedApplicationName))) .SetApplicationName(sharedApplicationName); builder.Services.AddAuthentication() .AddCookie("SharedCookie", options => options.Cookie.Name = ".AspNet.ApplicationCookie"); // Add services to the container. builder.Services.AddControllersWithViews(); builder.Services.AddSystemWebAdapters() .AddRemoteAppClient(remote => remote .Configure(options => { options.RemoteAppUrl = new(builder.Configuration["ReverseProxyAddress"]); options.ApiKey = "test-key"; }) .AddAuthentication(true) .AddSession()) .AddJsonSessionSerializer(options => options.KnownKeys.Add("Example", typeof(Example))); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { //app.UseExceptionHandler("/Home/Error"); //app.UseHsts(); } //app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseSystemWebAdapters(); app.MapGet("/current-principals-with-metadata", (HttpContext ctx) => { var user1 = Thread.CurrentPrincipal; var user2 = ClaimsPrincipal.Current; return "done"; }).WithMetadata(new SetThreadCurrentPrincipalAttribute(), new SingleThreadedRequestAttribute()); app.MapGet("/current-principals-no-metadata", (HttpContext ctx) => { var user1 = Thread.CurrentPrincipal; var user2 = ClaimsPrincipal.Current; return "done"; }); app.UseEndpoints(endpoints => { app.MapDefaultControllerRoute(); // This method can be used to enable session (or read-only session) on all controllers //.RequireSystemWebAdapterSession(); app.MapReverseProxy(); }); app.Run();
ASP.NET站点 Global.asax.cs 相关片段
GlobalConfiguration.Configure(WebApiConfig.Register); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); ViewEngines.Engines.Insert(0, new BillingViewEngine()); ViewEngines.Engines.Remove(ViewEngines.Engines.OfType<WebFormViewEngine>().FirstOrDefault()); LocalisationConfig.RegisterAdapters(); SystemWebAdapterConfiguration.AddSystemWebAdapters(this) .AddProxySupport(options => options.UseForwardedHeaders = true) .AddJsonSessionSerializer(options => options.KnownKeys.Add("Example", typeof(Example))) .AddRemoteAppServer(remote => remote .Configure(options => options.ApiKey = "test-key") .AddAuthentication() .AddSession());
求助
目前卡在此处,恳请提供解决思路或相关指引。
内容的提问来源于stack exchange,提问作者Andrew Hawker
相关产品推荐
相关产品推荐

