bleumink / streamlit-keycloak

User authentication and single sign-on in your Streamlit app using Keycloak
MIT License
59 stars 11 forks source link

Accessing Keycloak hosted on a another machine via IP address #15

Closed MPerrymanAW closed 1 year ago

MPerrymanAW commented 1 year ago

We are using Docker Images to run the elements required:

The basic use of the streamlit-keycloak login works fine when the Images are run and accessed on the same machine, the issue occurs when running the Images on one machine and access them on another. Due to various restrictions with the end environment of the project this is the scenario we have, for now we don't have a DNS setup just an IP address for accessing the machine with the Images.

Steps to follow:

  1. The UI site opens and loads the 'Sign in' button, clicking it pops up the Keycloak Login page
  2. The URL at the top of this login page is correct, it uses the IP address entered into the streamlit-keycloak login object
  3. But the HTML Form that is submitted when clicking the 'Sign In' button uses the localhost
  4. Inspecting this element and correcting the URL to use the IP address allows the Form to be submitted successfully and the login successful.

I'm new to all the code used here but as far as I can tell 'localhost' isn't hard-coded anywhere in the source code, the only references I can find are examples or test code. However looking in the Python package there is reference to 'localhost' but I can't tell what it's doing as the code has been compressed, eg: function(t){0==t.url.indexOf([http://localhost)&&(f(g(t.url),n),u(),c!=0)}]

Is this a bug in the keycloak.js, something Svelte is doing or something in the code?

CHerSun commented 1 year ago

I've read your text, but I didn't get what the problem is. Could you elaborate a bit? Which form? Why localhost is a problem (it should come from headers I guess, so that means you are indeed accessing from localhost?)?

I'm running a mini app using this component in our org - standalone Keycloak, app hosted on another host, everything wrapped in reverse proxy for HTTPS, and DNS ofc - everything works as expected.

MPerrymanAW commented 1 year ago

Thanks for the reply, I'm new to this networking stuff usually I'm working on the back-end of non-Docker systems.

We're hosting the Docker Containers on another machine (linux-based) that is currently being accessed via it's IP by a Windows-based machine via Firefox. So accessing the Streamlit UI is something like "1.2.3.4:8501", it displays the Title of the Project along with the streamlit-keycloak component: 01 - Sign in Clicking the 'Sign in' button displays the below Log in window (the IP address at the top matches the host's IP address at this point): 02 - Sign in popup But the HTML's form's action URL still contains the 'localhost' in the address: 03 - Sign in popup's HTML We can modify the URL in the action tag to use the IP address instead of the localhost and it logs in ok, if not then it fails to submit the form.

We're not using a reverse proxy, I saw that it's recommended to use one for Keycloak in a Production Environment but it worked when I was testing locally and it won't be used by many people (it may just be used on the host machine). I can't see how a reverse proxy would help in this situation as the browser still needs to access a site that isn't on localhost, does the use of the reverse proxy 'tell' the Log-in window the correct host name/IP address and therefore generates the correct submission URL? What is the configuration of your reverse proxy?

For now I've found how to port-forward with netsh: Redirecting a public URL to localhost with port The below command used for both ports (8501 for Streamlit & 8443 for Keycloak) allows me to access both sites using localhost URLs thus negating the 'fixed' localhost submission URL in the login form (with the 'connectaddress' being the host's IP address of course): netsh interface portproxy add v4tov4 listenport=8443 listenaddress=127.0.0.1 connectport=8443 connectaddress=1.2.3.4

CHerSun commented 1 year ago

2nd screenshot - is part of Keycloak already. Read its docs on setting the hostname. Here https://www.keycloak.org/server/hostname section called "Exposing the server without a proxy", if you don't want to use proxy, which could also do that as headers.

MPerrymanAW commented 1 year ago

Thanks for the reply, I did see the HOSTNAME setting but it didn't do anything other than error if it wasn't there. To sum up there are 2 solutions to this issue:

  1. Set the hostname-url as either an environment variable or via command-line switch: a. In the Dockerfile add "KC_HOSTNAME_URL=https://localhost:8443" which 'localhost' can then be updated to use the IP Address (or) b. Add "--hostname-url=https://localhost:8443" to the command line when starting the Keycloak server
  2. Use port redirects so that calls to localhost:8443 are redirected to the host IP Address: netsh interface portproxy add v4tov4 listenport=8443 listenaddress=127.0.0.1 connectport=8443 connectaddress=1.2.3.4