iFargle / headscale-webui

A simple Headscale web UI for small-scale deployments.
Other
619 stars 56 forks source link

OIDC return http not https address #114

Open lwdStudio opened 12 months ago

lwdStudio commented 12 months ago

I am trying to host a personal headscale with headscale-webui, with OIDC authentication with Azure AD. After config everything according to documentation, AAD prompts for incorrect redirect URI, which interesting it shows it is using http url instead of https.

图片_20230720145617

None of the debug log and config indicate what is wrong.

图片_20230720150008

Docker compose file help to indicate what is going on:

version: '3'
services:
  headscale:
    container_name: headscale
    volumes:
      - ./config:/etc/headscale
      - ./var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock
    ports:
      - 18080:8080
      - 19090:9090
    image: headscale/headscale:0.22.3
    restart: unless-stopped
    command: headscale serve
  headscale-webui:
    image: ghcr.io/ifargle/headscale-webui:latest
    container_name: headscale-webui
    environment:
      - TZ=Asia/Shanghai
      - COLOR=red # Use the base colors (ie, no darken-3, etc) - 
      - HS_SERVER=https://headscale.mydomain.com # Reachable endpoint for your Headscale server
      - DOMAIN_NAME=https://headscale.mydomain.com # The base domain name for this container.
      - SCRIPT_NAME=/admin # This is your applications base path (wsgi requires the name "SCRIPT_NAME").  Remove if you are hosing at the root /
      - KEY="<Redact>" # Generate with "openssl rand -base64 32" - used to encrypt your key on disk.
      - AUTH_TYPE=OIDC # AUTH_TYPE is either Basic or OIDC.  Empty for no authentication
      # ENV for OIDC (Used only if AUTH_TYPE is "OIDC").  Can be omitted if you aren't using OIDC
      - OIDC_AUTH_URL=https://login.microsoftonline.com/<Redact Telnet ID>/v2.0/.well-known/openid-configuration # URL for your OIDC issuer's well-known endpoint
      - OIDC_CLIENT_ID=<Redact> # Your OIDC Issuer's Client ID for Headscale-WebUI
      - OIDC_CLIENT_SECRET=<Redact> # Your OIDC Issuer's Secret Key for Headscale-WebUI
      - LOG_LEVEL=DEBUG # Log level.  "DEBUG", "ERROR", "WARNING", or "INFO".  Default "INFO"
    volumes:
      - ./webui:/data # Headscale-WebUI's storage.  Make sure ./volume is readable by UID 1000 (chown 1000:1000 ./volume)
      - ./config/:/etc/headscale/:ro # Headscale's config storage location.  Used to read your Headscale config.
    depends_on:
      - headscale
    ports:
      - 15000:5000
  derp:
    build: ./derp
    image: derp:latest
    container_name: derp
    restart: always
    depends_on:
      - headscale
    env_file:
      - .env
    ports:
      - 10443:443
      - 13478:3478
    volumes:
      - /etc/letsencrypt/live/mydomain.com/fullchain.pem:/cert/${DERP_DOMAIN}.crt
      - /etc/letsencrypt/live/mydomain.com/privkey.pem:/cert/${DERP_DOMAIN}.key
      - ./var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock

Could anyone help with this situation? Thank you.

ktims commented 9 months ago

This is caused because the behaviour of Flask OIDC is to build the redirect URI itself. As described in the doc, OVERWRITE_REDIRECT_URI needs to be set to the correct URI in the Flask OIDC settings. Unfortunately I don't think it's possible to fix without a patch.

This is what I did.

diff --git a/server.py b/server.py
index 85c0b79..e20cf29 100644
--- a/server.py
+++ b/server.py
@@ -75,6 +75,11 @@ if AUTH_TYPE == "oidc":
     with open("/app/instance/secrets.json", "r+") as secrets_json:
         app.logger.debug("/app/instances/secrets.json:")
         app.logger.debug(secrets_json.read())
+
+    if DOMAIN_NAME:
+        OVERWRITE_REDIRECT_URI = DOMAIN_NAME + BASE_PATH + "/oidc_callback"
+    else:
+        OVERWRITE_REDIRECT_URI = False

     app.config.update({
         'SECRET_KEY': secrets.token_urlsafe(32),
@@ -86,7 +91,8 @@ if AUTH_TYPE == "oidc":
         'OIDC_USER_INFO_ENABLED': True,
         'OIDC_OPENID_REALM': 'Headscale-WebUI',
         'OIDC_SCOPES': ['openid', 'profile', 'email'],
-        'OIDC_INTROSPECTION_AUTH_METHOD': 'client_secret_post'
+        'OIDC_INTROSPECTION_AUTH_METHOD': 'client_secret_post',
+          'OVERWRITE_REDIRECT_URI': OVERWRITE_REDIRECT_URI
     })
     from flask_oidc import OpenIDConnect
     oidc = OpenIDConnect(app)