markmnl
markmnl

Reputation: 11426

How to get URL client is coming from behind a reverse proxy?

I have a Controller Action in which I:

  1. Forward a URL to a 3rd party that the 3rd party re-directs the client to if an operation is successful.
  2. The client then connects to the 3rd party and performs an operation.
  3. If successful the 3rd party re-directs (using a 302) the client to the URL we told them at step 1.

This all works. Problem is the URL the Controller on the server tells the 3rd party about us built using:

var urlHelper = new UrlHelper(System.Web.HttpContext.Current.Request.RequestContext);
var responseUrl = urlHelper.Action("Action", "Controller", new { id }, Request.Url.Scheme);

responseURL now looks like:

"https://some.internal.domain/App/Action/1234".

The client however accessed the site using an address like:

"https://example.com/App/Action/1234".

and they cannot access https://some.internal.domain externally.

So how can I build the absolute URL for the 3rd party to re-direct the client to using the URL the client is accessing the site from?

UPDATE: The above method should have worked it turns out the problem is am behind a Reverse Proxy (have re-worded the title to reflect this).

Upvotes: 3

Views: 4380

Answers (1)

Frank Fu
Frank Fu

Reputation: 3643

I came across a similar problem. You basically have two options.

  1. Use the URL Rewrite Module to rewrite your entire response by replacing/rewriting all pattern matched with https://some.internal.domain to https://example.com/App. You'll probably want to add certain conditions like only rewrite if the response type is of type html/text and what not.

  2. Use an extension method. This method requires the Reverse Proxy in question to forward additional headers identifying where the original request came from (e.g. Azure Application Gateway sends a header named X-Original-Host but I think most other reverse proxies use X-Forwarded-For or some variant like Winfrasoft X-Forwarded-For). So based on the example provided you could do something like.

The helper could look like this

public static class UrlHelpers
{
    public static string GetUrlHostname(this UrlHelper url)
    {
        var hostname = url.RequestContext.HttpContext.Request.Headers["X-Original-Host"] ?? url.RequestContext.HttpContext.Request.Url.Host;
        return hostname;
    }
}

And then to use it based on your example.

var urlHelper = new UrlHelper(System.Web.HttpContext.Current.Request.RequestContext); 
var responseUrl = urlHelper.Action("Action", "Controller", new { id }, Request.Url.Scheme, urlHelper.GetUrlHostname());

Upvotes: 2

Related Questions