I have a legacy ASP.NET MVC application which I'd like to incrementally migrate to ASP.NET Core 8 app using YARP.
Imagine, that my legacy app is hosted under url foo.com, and my proxy app is hosted using url bar.com. When I go to the main page bar.com, authentication logic is triggered and I am redirected to bar.com/account/login, which displays content from foo.com/account/login. This works great for me. Here is my code:
var httpClient = new HttpMessageInvoker(new SocketsHttpHandler
{
UseProxy = false,
AllowAutoRedirect = false,
AutomaticDecompression = DecompressionMethods.None,
UseCookies = true,
EnableMultipleHttp2Connections = true,
ActivityHeadersPropagator = new ReverseProxyPropagator(DistributedContextPropagator.Current),
ConnectTimeout = TimeSpan.FromSeconds(60),
});
var transformer = HttpTransformer.Empty;
var requestOptions = new ForwarderRequestConfig();
app.MapForwarder("/{**catch-all}", app.Configuration["ProxyTo"], requestOptions, transformer, httpClient);
Now I'd like to switch from MapForwarder
to MapReverseProxy
. I changed my code accordingly
builder.Services.AddHttpForwarder();
builder.Services.AddReverseProxy()
.ConfigureHttpClient((context, handler) =>
{
handler.AllowAutoRedirect = false;
handler.UseProxy = false;
handler.EnableMultipleHttp2Connections = true;
handler.UseCookies = true;
handler.ConnectTimeout = TimeSpan.FromSeconds(60);
})
.LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
builder.Services.AddSystemWebAdapters()
.AddRemoteAppClient(options =>
{
options.RemoteAppUrl = new Uri(builder.Configuration
["ReverseProxy:Clusters:fallbackCluster:Destinations:fallbackApp:Address"]!);
options.ApiKey = builder.Configuration["RemoteAppApiKey"]!;
})
.AddAuthenticationClient(true);
...
app.MapReverseProxy();
Now, behavior changed. If handler.AllowAutoRedirect
is false
, then bar.com redirects to foo.com/account/login - I don't want to change domains.
If handler.AllowAutoRedirect
is true
, then bar.com displays content of foo.com/account/login - domain is not changed, but path /account/login
is not preserved.
What I am doing wrong?
my config is as simple as that:
"ReverseProxy": {
"Routes": {
"route1": {
"ClusterId": "fallbackCluster",
"Match": {
"Path": "{**catch-all}"
}
}
},
"Clusters": {
"fallbackCluster": {
"Destinations": {
"fallbackApp": {
"Address": "https://localhost:44311/"
}
}
}
}
},
Adding Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices
to legacy .NET Framework project and following line in Application_Start
fixed the behavior
this.AddSystemWebAdapters()
.AddProxySupport(options => options.UseForwardedHeaders = true);
package also installs modules and handlers in web.config
file
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<modules runAllManagedModulesForAllRequests="true">
<remove name="SystemWebAdapterModule" />
<add name="SystemWebAdapterModule" type="Microsoft.AspNetCore.SystemWebAdapters.SystemWebAdapterModule, Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices" preCondition="managedHandler" />
</modules>