We are trying to use the Microsoft.AspNetCore.SystemWebAdapters to implement a incremental move from a our existing ASP.NET MVC site to a ASP.NET Core MVC site. https://devblogs.microsoft.com/dotnet/incremental-asp-net-to-asp-net-core-migration/
After following the various guides and example projects supplied by MS I am hitting an error generated by a YARP protocol method which is called by the following method in the SystemWebAdapters:
public Task InvokeAsync(HttpContext context)
=> context.GetEndpoint()?.Metadata.GetMetadata() is { IsDisabled: false } ? SetUserAsync(context) : _next(context);
The follow exception is raised:
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)
Code
This is the code in the program.cs in the Core site, I'm not using SSL at the moment:
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();
This is the section from the 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());
Any pointers would be useful as I've hit a bit of a wall with it.