1

I currently have a site which take in all ingoing request and forward them to the correct website.

This is currently setup via this Yarp configuration:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ReverseProxy": {
    "Routes": {
      "server": {
        "ClusterId": "old-site",
        "Match": {
          "Path": "{**catch-all}"
        }
      },
      "azure": {
        "ClusterId": "new-site",
        "Match": {
          "Path": "yarpb"
        }
      }
    },
    "Clusters": {
      "old-site": {
        "Destinations": {
          "server": {
            "Address": "https://test-www.a.com/"
          }
        }
      },
      "new-site": {
        "Destinations": {
          "yarpb": {
            "Address": "https://example.com/"
          }
        }
      }
    }
  }
}

The entry point is test.a.com and which according to the redirect rule above will redirect to test-www.a.com.

This is fine, and works as it is supposed.

One site that seems problematic now is the cms backoffice umbraco, test.a.com/umbraco, which sometimes fetches files from the app_plugins folder.

Some of these files are fetched with CORS

enter image description here

which is causing an issue when the original html request is being redirected to a different page. enter image description here

Is it somehow possible let it pass through?

I have in the code tried this app.UseCors(x => x.AllowAnyOrigin()); but it does not seem to change anything?

its like this is being set after yarp redirect the request as yarp logging states 200 response, but the browser says 405?

Log snippet:

2022-06-21T17:48:02.6237461+02:00   INFO    [Yarp.ReverseProxy.Forwarder.HttpForwarder] [Forwarding]    Proxying to https://test-www.a.com/App_Plugins/RJP.MultiUrlPicker/MultiUrlPicker.html HTTP/2 RequestVersionOrLower no-streaming
2022-06-21T17:48:02.6255128+02:00   INFO    [Yarp.ReverseProxy.Forwarder.HttpForwarder] [ResponseReceived]  Received HTTP/2.0 response 301.
2022-06-21T17:48:02.6256100+02:00   INFO    [ReverseProxy.Middleware.RequestResponseLoggerMiddleware]   [LogRequest]    https://test.a.com/App_Plugins/RJP.MultiUrlPicker/MultiUrlPicker.html proxied to https://test-www.a.com//App_Plugins/RJP.MultiUrlPicker/MultiUrlPicker.html
2022-06-21T17:48:02.6273081+02:00   INFO    [Yarp.ReverseProxy.Forwarder.HttpForwarder] [ResponseReceived]  Received HTTP/2.0 response 200.

entire program.cs

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddReverseProxy().LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
builder.Services.AddLogging(x =>
{
    x.AddJsonConsole();
    x.AddFile($"logs/app-{DateTime.UtcNow:yyyyMMddHHmmss}.log", append: true);
});

var app = builder.Build();


app.UseStaticFiles();
app.UseRouting();
app.UseCors(x => x.AllowAnyOrigin());

app.MapReverseProxy(proxyPipeline =>
{
    proxyPipeline.UseRequestResponseLogging();
});

app.Run();
J.Down
  • 700
  • 1
  • 9
  • 32
  • Having had a similar battle with CORs recently, I would first say to double-check that things are doing what you think they are (I had a DNS entry pointing to the wrong place). You cannot configure cors to be let through because that's not how it works. The *browser* will send the Origin header if it is a certain type of request to a different origin. The CORs middleware will react if it sees that header and has CORs enabled to reply Access-Control-Allow-Origin: yoursite. If this isn't working then whatever is server the resources doesn't have CORs correctly configured. – Luke Briner Jun 23 '22 at 09:00
  • Some investigaction has shown that this issue only exist for one particular plugin, namely the multiurl plugin for umbracoi7. Nothing in the code seem to indicate that requesting this required cors on? So I am bit confused on why this specifically need one? https://github.com/rasmusjp/umbraco-multi-url-picker – J.Down Jun 27 '22 at 08:30
  • Are you using NTLM auth ? Ntml uses `OPTION` http header and does not allow wildcard CORS hosts – Claudio Jun 28 '22 at 13:34
  • Please take a look at [Enable Cross-Origin Requests (CORS) in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-6.0) and [Enable CORS in Web API 2](https://stackoverflow.com/questions/18619656/enable-cors-in-web-api-2) – Eskandar Abedini Jun 29 '22 at 06:19

4 Answers4

1

So after some investigation i finally managed to fix the issue via yarp, by modifiying the response header location to be the same as the request header.

.AddTransforms(builderContext =>
{
    builderContext.AddResponseTransform(async context => {
    if (context.HttpContext.Response.StatusCode == 302 || context.HttpContext.Response.StatusCode == 301)
    {
        if (context.ProxyResponse == null)
        {
            return;
        }

        var proxyResponse = context.ProxyResponse.Headers;
        var oldLocation = context.HttpContext.Response.GetTypedHeaders().Location;

        if (oldLocation == null)
        {
            return;
        }

        var oldLocationScheme = oldLocation.Scheme;
        var oldLocationHost = oldLocation.Host;
        var oldLocationsPath = oldLocation.AbsolutePath;
        var newLocation = new UriBuilder()
        {
            Scheme = oldLocationScheme,
            Host = oldLocationHost,
            Path = oldLocationsPath
        }.Uri;

        context.HttpContext.Response.GetTypedHeaders().Location = proxyResponse.Location = newLocation;
        context.SuppressResponseBody = true;
    }
});
J.Down
  • 700
  • 1
  • 9
  • 32
-2

From the documentation it seems that you need to map your entries to use CORS by calling RequireCors method.

It also seems that it is better for you to construct a policy, add the desired origins to that policy and then map your entries to the policy. That way - any change to the policy will immediately affect all registered end-points.

Also, beware that when you are using a wildcard inside your CORS config, you may disable other functionality in modern browsers (MDN to the rescue). So please - try to specify your own domain to ensure everything works as excepted

ymz
  • 6,602
  • 1
  • 20
  • 39
  • Tried did not work :/ – J.Down Jul 01 '22 at 12:04
  • 1
    a relevant exception or a log will be highly appreciated and also - a little bit more constructive than just "it does not work for me". just saying :) – ymz Jul 03 '22 at 09:46
-2

Add following in Configure

app.UseCors(options => options.SetIsOriginAllowed(x => _ = true).AllowAnyMethod().AllowAnyHeader().AllowCredentials());
Upender Reddy
  • 568
  • 3
  • 8
-2

Add this to service in ConfigureServices:

        services.AddCors(options =>
        {
            options.AddDefaultPolicy(
            builder =>
            {
                builder.AllowAnyOrigin()
                       .AllowAnyHeader()
                       .AllowAnyMethod();
            });
        });