Authentication URL is using internal hostname

I have…

  • [x] Checked the logs and have provided the logs if I found something suspicious there

I’m submitting a…

  • [ ] Regression (a behavior that stopped working in a new release)
  • [x] Bug report
  • [ ] Performance issue
  • [ ] Documentation issue or request

Current behavior

I’m using Squidex behind a reverse proxy and configured the baseUrl property. X-Forwarded-Proto and X-Forwarded-For are set. The Uri that’s generated for the authentication page is https://internal domain name/identity-server/Account/Login?ReturnUrl=%…

Expected behavior

I expected that the baseUrl property would be used for this URL. Or am I missing something here??

Minimal reproduction of the problem

Run behind reverse proxy (Barracuda WAF) with different internal hostname.

Environment

  • [ ] Self hosted with docker
  • [ ] Self hosted with IIS
  • [X] Self hosted with other version (Azure webapp)
  • [ ] Cloud version

Version: 4.0.2

Browser:

  • [x] Chrome (desktop)
  • [ ] Chrome (Android)
  • [ ] Chrome (iOS)
  • [ ] Firefox
  • [ ] Safari (desktop)
  • [ ] Safari (iOS)
  • [ ] IE
  • [ ] Edge

Others:

Can you show me your config?

I’ve sent you a direct message with our config.

I have done a bit of digging into this issue. Our web application firewall/reverse proxy rewrites the Host header. This is required since the distinction between apps in our app service environment is based on the internal hostname.

This seems to be no issue except for the identityserver part which will use the hostname no configure its service.

I see two approaches in solving this:

  • Add an option to the identity configuration e.g. EnableIdentityServerHostname. And within IdentityServerServices.cs explicitly set the Identityserver publicorigin to the value of the baseUrl when this option is enabled
  • Use the forwardedheaders functionality. Change the WebExtensions.cs UseSquidexForwardingRules function. And add the XForwardedHost header as a forwarded header. Limit the allowed hosts by setting the allowed hosts option to the host of the configured baseUrl. Only do this when a baseUrl is provided. Result will be that when a X-Forwarded-Header is present and it matches the host of the baseUrl it will change the HttpContext to this forwarded hostname.

@Sebastian I can make you a pr. Do you have a preference on this approach?

I think the first option would be make sense. But I am not really sure if it works, I struggled with a similar problem, but cannot remember how I have solved it.

We can also write a middleare which sets the host and protocol from the base url config.

I’ve tested both ways and those seem to work. The second one seems more generic. This problem occurs when the hostname is rewritten in a proxy. This normally comes with a x-forwarded-host header. So using this header limits this fix to only this scenario (when the header is not present/does not match the baseUrl it won’t do anything). And it doesn’t require an additional configuration field.

(and you are already using this middleware)

The best case would be if you would not need the base url at all, but some users had scenarios where a proxy did not forward the url and I also need the host name in a few other places, e.g. when configuring the allowed redirect urls.

I mean theoretically we do no t need the X-Forwarded headers at all because we use the base url

Ok. From that point of view it makes sense to always use the baseurl as the publicorigin of identityserver.

See: https://github.com/Squidex/squidex/pull/456

Just found out that the Microsoft Authentication also uses the actual hostname of the request. So above fix fixes the IdentityServer part. But it results in an exception when validating the token you get from Azure AD for example.

So bottom line. I’m only able to get this working with a revers proxy by using the X-Forwarded-Host header.

I’ll send you a new PR.