Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(Guidance 2022.2.1.14) Set all the forwarded headers, not only the prefix #235

Open
vvdb-architecture opened this issue Mar 25, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@vvdb-architecture
Copy link
Contributor

Currently, the guidance generates code in the back-end services that fills in the PathBase with the contents of X-Forwarded-Prefix value (if present), to correct the base paths used in various scenarios:

 // Always replace the virtual path of this backend with the one from the yarp. Required for swagger and hangfire when hosted in IISHost!
        app.Use((context, next) =>
        {
            var pathBase = context.Request.Headers["X-Forwarded-Prefix"];
            if (!string.IsNullOrWhiteSpace(pathBase))
                context.Request.PathBase = new PathString(pathBase);
            return next();
        });

This works because it assumes that the service shares the same host name and scheme as the Yarp. In fact, it is assumed that the PathBase is always /Yarp, except in Development scenarios where the PathBase will be empty (because the Yarp is also hosted on localhost, but using another port).

However, if a controller method needs to compute the URI of its endpoint, it should be able to compute it like this:

                var uriBuilder = new UriBuilder(Request.Scheme, Request.Host.Host);
                if (Request.Host.Port is not null)
                    uriBuilder.Port = Request.Host.Port.Value;
                uriBuilder.Path = Request.PathBase.ToUriComponent() + "/whatever";

                var endpoint = uriBuilder.ToString();

This works except in Development scenarios. because the Host will still be the service host, not the Yarp host!

To correct this, the above code should also set the other forwarded headers like this:

        // Always replace the scheme, host and pathbase of this backend with the ones forwarded by Yarp. Required for swagger and hangfire when hosted in IISHost!
        app.Use((context, next) =>
        {
            const string HeadedrPrefix = "X-Forwarded-";    // this can change

            var pathBase = context.Request.Headers[HeadedrPrefix + "Prefix"];
            if (!string.IsNullOrWhiteSpace(pathBase))
                context.Request.PathBase = new PathString(pathBase);

            var forwardedHost = context.Request.Headers[HeadedrPrefix + "Host"];
            if (!string.IsNullOrWhiteSpace(forwardedHost))
                context.Request.Host = HostString.FromUriComponent(forwardedHost);

            var forwardedProto = context.Request.Headers[HeadedrPrefix + "Proto"];
            if (!string.IsNullOrWhiteSpace(forwardedProto))
                context.Request.Scheme = forwardedProto;

            return next();
        });

Note that the X-Forwarded- has been explicitly factored out, since this is something that can be changed (see The section about X-Forwarded- in the documentation).

@rdarko rdarko added the bug Something isn't working label Apr 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants