Managing Redirect when proxying a Web UI

Hi all,

I would like to access to a UI server through Kong in order to perform some authentication and counts thanks to standard and custom plugins.

The Web Browser is navigating the Web UI though Kong proxy API, using the url http://kong:8000/ui. Kong then proxies the calls to the upstream url http://uiserver:8080

The issue I have is that the UI server performs several 302 Moved redirections: unfortunately, the Location header set by the UI server is using http://uiserver:8080 as base URL, and this Location value does not make sense for the Web Browser as the Web Browser only knows the http://kong:8000/ui base URL.

How can I configure Kong so that the Location URL is transformed into the “downstream representation”, and not the “upstream representation” ?

Unfortunately I don’t have the capability to modify the UI Server to return a relative URL instead of a full one…

Thanks for your help.

2 Likes

Hi again,

I’m partially answering to my own question: usage of the preserve_host attribute in the API declaration enables to keep the “external” Host (i.e. uiserver in my example above) in the Location redirect header, instead of the Kong host (kong). That’s already a good step !.. but, I now have an issue on the path !

To explain this, I need to go deeper into the explanations of my urls, sorry for that… Indeed if I take the plain UI Server, it is always using a common root path /theUI and all links and redirect URLs are under this /theUI path.
I have no issue if I create a Kong API with the uris field set to “/theUI” and with strip_uri set to false… but I don’t want this because “theUI” keywork is a reserved keyword for my application: I cannot use it explicitly as root path for the UI server :frowning:

So I would like to declare an API in Kong with a uris field set to “/ui”, the UI Server being now accessible when I use http://kong:8000/ui/theUI (strip_uri set to true)… but then, the value of the Location Header of the response is not good: it is http://kong:8000/theUI/xxx: the host is managed properly… but not the path because I lost the /ui/ due to the strip_uri being set to true, and then no way to navigate the redirected URI through Kong (Kong does not have API declared on /theUI; it is declared on /ui) !
What about setting strip_uri to false? This does not work because this time this is the very first request that will not route to my UI Server (because the upstream URI http://uiserver:8080/theUI/ui does not exist :tired_face: )

As a summary, it looks I would need a new preserve_stripped_path parameter that would add back in the Location header of the response the part of the URI that has been cut/stripped when processing the request!
And maybe not only in the Location header; this is true also for all URLs that may have been returned as links of the UI’s html or php or… returned pages! It looks like the “reverse proxy pass” feature of an Apache server…

And more than that, isn’t it the same issue if I have a REST endpoint (I’m no longer talking about a UI at all) that returns JSONs containing URLs of other resources: the resource server might consider the usage of the Host header for the domain name, but no way to consider the part of the path that has been cut by the “URI stripping mechanism” of Kong ! Only Kong can add back this cut/stripped part of the urls…

Any idea to addess this issue on the path?

1 Like

Hi,

Kong isn’t built to play well with UIs and redirects (in fact, I would advise against using Kong in front of a website). Maybe you could develop a plugin of your own that would handle the rewriting of those Location headers, and/or controlling what the upstream call’s URL looks like (bot of which are achievable with a custom plugin and minimum amount of work).

You could maybe avoid having to do that with defining multiple APIs with different matching and stripping rules, but I haven’t taken a look myself (your requirements and issues are confusing to read in your message).

2 Likes

Hi @thibaultcha

I’m a bit surprised by your statement “I would advise against using Kong in front of a website” : Kong Enterprise Edition includes an OpenID Connect plugin which role is definitely to protect a web site by providing OIDC authentication flows!

I don’t understand what differs from one use case (Kong’s EE plugin protecting a web site) to the other (mine, just proxying a website)?

1 Like

OpenID Connect can be used not only for websites. The suite of OIDC plugins in Kong EE perform several specific roles, but none of them include arbitrary web proxying. The Authentication plugin implements OIDC’s specific authentication flow only, and the Protection plugin is used to proxy APIs in an OIDC-authenticated manner.

Ok, fair, I was so concentrated on web UI management ! :wink:
In addition to the Location header management, what would be missing up to you in Kong Core in order to proxy a web site (so to be implemented as a custom plugin) ?

@thibaultcha, what do you mean exactly by “controlling what the upstream call’s URL looks like”?

Thanks for your help

@thibaultcha, what do you mean exactly by “controlling what the upstream call’s URL looks like”?

I mean the URL of the request made by Kong to your upstream service. This value is configurable from plugins via the ngx.var.upstream_uri variable.

Same issue on myside : I cannot manage to avoid Kong redirecting my web UI instead of reverse proxy it.

@Pamiel did you manage to do it ?

Hi @julienlau,

I’m not sure to understand your concern, sorry for that ! Could you please clarify the issue you have (you cannot “avoid” redirection ??) ?

On my side, the issue was that when a redirection was sent (on purpose) by an upstream Web UI server, then the URL contained in the Location HTTP Header was containing an “internal” URL, and not a URL that could be navigated by the web browser.

Indeed, as far as I remember, I solved my issue by using the X-Forwarded-Host header (and by setting the trusted_ips configuration parameter of Kong to enable the transmission of the X-Forwarded-* headers) and implementing correctly the Web UI upstream server:

  • All URLs generated in response (e.g. in the HTML or JS) should be relative.
  • Web UI server shall be accessible directly on “/”
  • In case an absolute URL is required (for example in the Locationheader), then the “host” part of this URL shall be taken from X-Forwarded-Host and not in the incoming URL.

Does this make sense for your problem?

Hi pamiel,
thank you for your quick answer. Your tip regarding serving on “/” helped me.

I have a setup with a node running Kong to load balance API located in a VLAN (private network). Kong is also used to expose those API to the public. This is running OK.

I wanted to use Kong to reverse proxy a web UI located in this VLAN in order to expose it to the public but using Kong for SSL and Auth. I have trouble with this.

It seems to work when the web server in the private VLAN servers static html on “/”, but I cannot make it work otherwise. If on this static server on a Vlan I put an index.html in a subdir for example “nifi” I cannot reach it through Kong. More precisely this route won’t work:
http://mykong/myPrivateNifi
but this route works:
http://mykong/myPrivateNifi/index.html

This is a test but in the end the UI I want to serve is a war (nifi-web-ui-1.6.0.war from apache nifi).

I think I’d better try to use custom nginx template to directly setup a reverse proxy.

Thanks

Isn’t it linked to a missing ending slash for your first URI ?

Web servers might interpret differently http://mykong/myPrivateNifi (without ending slash) and http://mykong/myPrivateNifi/ (with a ending slash): in first case, it is a file named myPrivateNifi within the myKong directory (this file does not exist!) while in the second one, it is the myPrivateNifi leaf directory, which is often processed by web server using the following rules: “if URL targets a directory, then try to get the index.html (or index.php or…) file located inside this directory”.
Can you try again with this ending slash (I don’t remember how Kong reacts to such ending slashes…)?

Thanks for the help.

I tried adding the trailing slash on the Kong service side and it has no effect.

However adding the trailing slash on client side helps.

However, I also needed to adapt the service so as to remove the strip_path option on the route so that it works for my nifi war web UI.

See configuration on images enclosed.
Host myKong has a public IP and a private Ip 192.168.1.2
Host 192.168.1.3 is only on private network.


And requests below:
curl -i myKong:8080/myPrivateHtml -> OK
curl -i myKong:8080/myPrivateHtmlSubdir -> KO
curl -i myKong:8080/myPrivateHtmlSubdir/ -> OK
curl -i myKong:8080/myPrivateHtmlSubdirTrailingSlash -> KO
curl -i myKong:8080/myPrivateHtmlSubdirTrailingSlash/ -> OK
curl -i myKong:8080/nifi-test -> KO (302)
curl -i myKong:8080/nifi-test/ -> KO: HTTP is 200, but the war fails to found some dependency due to path
Example : Request URL: http://mykong:8080/nifi-docs/html/expression-language-guide.html
Request Method: GET Status 404…
curl -i myKong:8080/nifi -> KO (302)
curl -i myKong:8080/nifi/ -> OK

Too bad I cannot tweak the strip_path to work correctly because, I would like to address multiples nodes running this nifi web UI on my Vlan.

fyi, this PR was just merged and changes the way the paths are build: https://github.com/Kong/kong/pull/3780 this might be of interest.

1 Like

Hi,
I am also trying to make my UI application publicly available via Kong, but getting issue while authentication, as its redirection URL is different from the downstream URL.

Its forwarding its upstream URL instead of actual URL for authentication.

Can anyone help configuring X-Forwarder-Host ? How I can configure it in my kong.conf

My existing kong.cong

plugins = custom_plugins
trusted_ips = x.x.x.x/x
real_ip_header = X-Forwarded-For
read_ip_recursive = on

@pamiel @julienlau

@pamiel @kailashvermaa got any solution for this ? , is there any way to preserve kong domain on address bar ?.. Its actually redirecting to my upstream web application