Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OIDC Discovery fails #2896

Open
Robinyo opened this issue Jan 1, 2025 · 3 comments
Open

OIDC Discovery fails #2896

Robinyo opened this issue Jan 1, 2025 · 3 comments

Comments

@Robinyo
Copy link

Robinyo commented Jan 1, 2025

OAuth2-Proxy Version

7.7.1

Provider

oidc

Expected Behaviour

For OAuth2 Proxy to successfully complete OIDC Discovery.

OIDC Discovery fails using the following providers:

  • oidc
  • keycloak
  • keycloak-oidc

Current Behaviour

OAuth2 Proxy exited with code 1:

oauth2-proxy  | [2025/01/01 20:42:43] [provider.go:55] Performing OIDC Discovery...
oauth2-proxy  | [2025/01/01 20:42:43] [main.go:59] ERROR: Failed to initialise OAuth2 Proxy: error initialising provider: could not create provider data: error building OIDC ProviderVerifier: could not get verifier builder: error while discovery OIDC configuration: failed to discover OIDC configuration: error performing request: Get "http://127.0.0.1:5001/realms/hapi-fhir-dev/.well-known/openid-configuration": dial tcp 127.0.0.1:5001: connect: connection refused
oauth2-proxy exited with code 1

However curl works as expected:

curl http://127.0.0.1:5001/realms/hapi-fhir-dev/.well-known/openid-configuration

For example:

{
    "issuer": "http://127.0.0.1:5001/realms/hapi-fhir-dev",
    "authorization_endpoint": "http://127.0.0.1:5001/realms/hapi-fhir-dev/protocol/openid-connect/auth",
    "token_endpoint": "http://127.0.0.1:5001/realms/hapi-fhir-dev/protocol/openid-connect/token",
    "introspection_endpoint": "http://127.0.0.1:5001/realms/hapi-fhir-dev/protocol/openid-connect/token/introspect",
    "userinfo_endpoint": "http://127.0.0.1:5001/realms/hapi-fhir-dev/protocol/openid-connect/userinfo",
    "end_session_endpoint": "http://127.0.0.1:5001/realms/hapi-fhir-dev/protocol/openid-connect/logout",
    "frontchannel_logout_session_supported": true,
    "frontchannel_logout_supported": true,
    "jwks_uri": "http://127.0.0.1:5001/realms/hapi-fhir-dev/protocol/openid-connect/certs",
    "check_session_iframe": "http://127.0.0.1:5001/realms/hapi-fhir-dev/protocol/openid-connect/login-status-iframe.html",
    "grant_types_supported": [
        "authorization_code",
        "implicit",
        "refresh_token",
        "password",
        "client_credentials",
        "urn:openid:params:grant-type:ciba",
        "urn:ietf:params:oauth:grant-type:device_code"
    ],
  
  ...

}

Steps To Reproduce

Blog post: https://rob-ferguson.me/add-authn-to-hapi-fhir-with-oauth2-proxy-nginx-and-keycloak-part-2/
Sample project: https://github.com/Robinyo/hapi-fhir-au

Possible Solutions

No response

Configuration details or additional information

.env:

PROTOCOL=http
# Postgres
POSTGRES_DB=hapi-fhir
POSTGRES_USER=admin
POSTGRES_PASSWORD=secret
COOKIE_NAME=oauth2-proxy
COOKIE_SECRET=uzVUu9BdSpOXqPeMaGoTYuTHazRXWoUCajyLUfWlnv8=
# Keycloak
KEYCLOAK_HOSTNAME=127.0.0.1
KEYCLOAK_PORT=5001
KEYCLOAK_REALM=hapi-fhir-dev
KEYCLOAK_ADMIN=admin
KEYCLOAK_ADMIN_PASSWORD=secret
# OAuth Client
CLIENT_ID=oauth2-proxy
CLIENT_SECRET=aHkRec1BYkfaKgMg164JmvKu8u9iWNHM
# OAuth2 Proxy
OAUTH2_PROXY_HOSTNAME=127.0.0.1
OAUTH2_PROXY_PORT=4180

docker-compose.yml:

---

services:

  postgres:
    container_name: postgres
    build:
      context: ./services/postgres
      dockerfile: Dockerfile
    # restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
      start_period: 20s
      interval: 30s
      retries: 5
      timeout: 5s
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: ${POSTGRES_DB:-hapi-fhir}
      POSTGRES_USER: ${POSTGRES_USER:-admin}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-secret}

  redis:
    container_name: redis
    build:
      context: ./services/redis
      dockerfile: Dockerfile
    command: --save 60 1 --loglevel warning
    # restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
      start_period: 20s
      interval: 30s
      retries: 5
      timeout: 3s
    volumes:
      - cache:/data

  keycloak:
    container_name: keycloak
    build:
      context: ./services/keycloak
      dockerfile: Dockerfile
    # restart: unless-stopped
    healthcheck:
      test: "bash /opt/keycloak/health-check.sh"
      interval: 5s
      timeout: 10s
      retries: 12
    command:
      [
        'start-dev',
        '--log-level=INFO,io.vertx.ext.web.impl.RouterImpl:TRACE',
        '-Dkeycloak.migration.action=import',
        '-Dkeycloak.migration.provider=singleFile',
        '-Dkeycloak.migration.realmName=hapi-fhir-dev',
        '-Dkeycloak.migration.strategy=OVERWRITE_EXISTING',
        '-Dkeycloak.migration.file=/import/development-realm.json',
      ]
    environment:
      KC_HOSTNAME: ${KEYCLOAK_HOSTNAME:-127.0.0.1}
      KC_HOSTNAME_PORT: ${KEYCLOAK_PORT:-5001}
      KC_HOSTNAME_STRICT_BACKCHANNEL: false
      KC_HTTP_ENABLED: true
      KC_HOSTNAME_STRICT_HTTPS: false
      KC_HEALTH_ENABLED: true
      KC_BOOTSTRAP_ADMIN_USERNAME: ${KEYCLOAK_ADMIN:-admin}
      KC_BOOTSTRAP_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD:-secret}
      KC_DB: postgres
      KC_DB_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-hapi-fhir}
      KC_DB_USERNAME: ${POSTGRES_USER:-admin}
      KC_DB_PASSWORD: ${POSTGRES_PASSWORD:-secret}
    ports:
      - ${KEYCLOAK_PORT:-5001}:8080
    volumes:
      - .:/import
      - ./services/keycloak/health-check.sh:/opt/keycloak/health-check.sh
    depends_on:
      postgres:
        condition: service_healthy

  hapi-fhir:
    container_name: hapi-fhir
    build:
      context: ./services/hapi-fhir
      dockerfile: Dockerfile
    # restart: unless-stopped
    environment:
      SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-hapi-fhir}
      SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-admin}
      SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-secret}
      SPRING_DATASOURCE_DRIVERCLASSNAME: "org.postgresql.Driver"
      SPRING_JPA_PROPERTIES_HIBERNATE_DIALECT: "ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgresDialect"
    configs:
      - source: hapi
        target: /app/config/application.yaml
    depends_on:
      postgres:
        condition: service_healthy

  oauth2-proxy:
    container_name: oauth2-proxy
    build:
      context: ./services/oauth2-proxy
      dockerfile: Dockerfile
    # restart: unless-stopped
    command:
      [
        '--standard-logging=true',
        '--auth-logging=true',
        '--request-logging=true',
        '--skip-auth-preflight=true',
      ]
    environment:

      # https://developer.okta.com/blog/2022/07/14/add-auth-to-any-app-with-oauth2-proxy
      # https://oauth2-proxy.github.io/oauth2-proxy/configuration/providers/openid_connect
      # https://oauth2-proxy.github.io/oauth2-proxy/configuration/providers/keycloak
      # https://oauth2-proxy.github.io/oauth2-proxy/configuration/providers/keycloak_oidc

      # Provider config
      # OAUTH2_PROXY_SKIP_OIDC_DISCOVERY: true
      OAUTH2_PROXY_PROVIDER: oidc
      OAUTH2_PROXY_PROVIDER_DISPLAY_NAME: OpenID Connect
      # OAUTH2_PROXY_PROVIDER: keycloak
      # OAUTH2_PROXY_PROVIDER_DISPLAY_NAME: Keycloak
      # OAUTH2_PROXY_PROVIDER: keycloak-oidc
      # OAUTH2_PROXY_PROVIDER_DISPLAY_NAME: Keycloak OIDC

      # https://github.com/oauth2-proxy/oauth2-proxy/issues/2117#issue-1712501553
      # AUTH2_PROXY_OIDC_EXTRA_AUDIENCE: ${CLIENT_ID}
      OAUTH2_PROXY_OIDC_EXTRA_AUDIENCE: account

      OAUTH2_PROXY_REDIRECT_URL: ${PROTOCOL}://${OAUTH2_PROXY_HOSTNAME}:${OAUTH2_PROXY_PORT}/oauth2/callback
      OAUTH2_PROXY_OIDC_ISSUER_URL: ${PROTOCOL}://${KEYCLOAK_HOSTNAME}:${KEYCLOAK_PORT}/realms/${KEYCLOAK_REALM}
      OAUTH2_PROXY_UPSTREAMS: http://hapi-fhir
      # OAUTH2_PROXY_EMAIL_DOMAIN: "*"
      OAUTH2_PROXY_EMAIL_DOMAINS: "*"

      # OAUTH2_PROXY_CODE_CHALLENGE_METHOD: S256

      # OAuth2 client configuration
      OAUTH2_PROXY_CLIENT_ID: ${CLIENT_ID}
      OAUTH2_PROXY_CLIENT_SECRET: ${CLIENT_SECRET}

      # https://devforum.okta.com/t/add-auth-to-any-app-with-oauth2-proxy/21255/13
      OAUTH2_PROXY_SCOPE: "openid email profile offline_access"

      OAUTH2_PROXY_PASS_ACCESS_TOKEN: true

      # Cookie configuration
      OAUTH2_PROXY_COOKIE_NAME: ${COOKIE_NAME}
      OAUTH2_PROXY_COOKIE_SECRET: ${COOKIE_SECRET}
      # OAUTH2_PROXY_COOKIE_DOMAIN:  127.0.0.1
      # OAUTH2_PROXY_COOKIE_DOMAINS: ${OAUTH2_PROXY_HOSTNAME}:${OAUTH2_PROXY_PORT}
      # OAUTH2_PROXY_COOKIE_DOMAINS:  "*"
      # OAUTH2_PROXY_COOKIE_DOMAINS:  127.0.0.1:4180
      # OAUTH2_PROXY_COOKIE_DOMAINS:  127.0.0.1
      OAUTH2_PROXY_COOKIE_SAMESITE: lax
      OAUTH2_PROXY_COOKIE_HTTPONLY: true
      OAUTH2_PROXY_COOKIE_SECURE: false
      OAUTH2_PROXY_COOKIE_EXPIRE: 10m
      OAUTH2_PROXY_COOKIE_REFRESH: 5m
      OAUTH2_PROXY_COOKIE_CSRF_PER_REQUEST: true

      OAUTH2_PROXY_HTTP_ADDRESS: 0.0.0.0:${OAUTH2_PROXY_PORT}


      # OAUTH2_PROXY_WHITELIST_DOMAINS: .${OAUTH2_PROXY_HOSTNAME}:${OAUTH2_PROXY_PORT}
      OAUTH2_PROXY_WHITELIST_DOMAINS: ${OAUTH2_PROXY_HOSTNAME}:${OAUTH2_PROXY_PORT}
      OAUTH2_PROXY_INSECURE_OIDC_ALLOW_UNVERIFIED_EMAIL: true
      OAUTH2_PROXY_SSL_UPSTREAM_INSECURE_SKIP_VERIFY: true
      OAUTH2_PROXY_SSL_INSECURE_SKIP_VERIFY: true
      OAUTH2_PROXY_ERRORS_TO_INFO_LOG: true
      OAUTH2_PROXY_SHOW_DEBUG_ON_ERROR: true


      # OAUTH2_PROXY_SKIP_OIDC_DISCOVERY: true
      OAUTH2_PROXY_LOGIN_URL: ${PROTOCOL}://${KEYCLOAK_HOSTNAME}:${KEYCLOAK_PORT}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/auth
      OAUTH2_PROXY_REDEEM_URL: ${PROTOCOL}://${KEYCLOAK_HOSTNAME}:${KEYCLOAK_PORT}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token
      OAUTH2_PROXY_OIDC_JWKS_URL: ${PROTOCOL}://${KEYCLOAK_HOSTNAME}:${KEYCLOAK_PORT}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/certs
      OAUTH2_PROXY_PROFILE_URL: ${PROTOCOL}://${KEYCLOAK_HOSTNAME}:${KEYCLOAK_PORT}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/userinfo
      OAUTH2_PROXY_VALIDATE_URL: ${PROTOCOL}://${KEYCLOAK_HOSTNAME}:${KEYCLOAK_PORT}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/userinfo


      # https://github.com/oauth2-proxy/oauth2-proxy/issues/628
      OAUTH2_PROXY_PASS_AUTHORIZATION_HEADER: true



      # https://github.com/oauth2-proxy/oauth2-proxy/issues/2890
      OAUTH2_PROXY_SKIP_JWT_BEARER_TOKENS: true
      OAUTH2_PROXY_SET_XAUTHREQUEST: true
      OAUTH2_PROXY_SKIP_AUTH_STRIP_HEADERS: false
      OAUTH2_PROXY_SKIP_AUTH_PREFLIGHT: true



      # OAUTH2_PROXY_REVERSE_PROXY: true
      OAUTH2_PROXY_REVERSE_PROXY: false
      OAUTH2_PROXY_SILENCE_PING_LOGGING: true

      # Session storage
      OAUTH2_PROXY_REDIS_CONNECTION_URL: redis://redis
      OAUTH2_PROXY_SESSION_STORE_TYPE: redis

    ports:
      - ${OAUTH2_PROXY_PORT:-4180}:4180
    depends_on:
      redis:
        condition: service_healthy
      keycloak:
        condition: service_healthy

volumes:
  postgres_data:
    driver: local
  cache:
    driver: local

configs:
  hapi:
    file: ./hapi.application.yaml
    # file: hapi.application-fhir-au-core-1.0.0-preview.yaml
@jjlakis
Copy link
Contributor

jjlakis commented Jan 3, 2025

This look to be related with networking. You can access keycloak via 127.0.0.1:5001 on the host, because you created port mapping from container to the host, but oauth2-proxy itself doesn't run in the host network, so it can't resolve this local IP (it runs in the docker-compose provider network).

Services in docker compose network can be discovered by each other simply by using their names. Which means that hostname http://keycloak:5001 should be accessible from oauth2-proxy instance. Let me know if this helps.

@Robinyo
Copy link
Author

Robinyo commented Jan 4, 2025

Thanks for getting back to me :)

Pretty sure I tried what you have suggested, just tried it again now.

PROTOCOL=http
# Postgres
POSTGRES_DB=hapi-fhir
POSTGRES_USER=admin
POSTGRES_PASSWORD=secret
COOKIE_NAME=oauth2-proxy
COOKIE_SECRET=uzVUu9BdSpOXqPeMaGoTYuTHazRXWoUCajyLUfWlnv8=
# Keycloak
# KEYCLOAK_HOSTNAME=127.0.0.1
KEYCLOAK_HOSTNAME=keycloak
KEYCLOAK_PORT=5001
KEYCLOAK_REALM=hapi-fhir-dev
KEYCLOAK_ADMIN=admin
KEYCLOAK_ADMIN_PASSWORD=secret
# OAuth Client
CLIENT_ID=oauth2-proxy
CLIENT_SECRET=aHkRec1BYkfaKgMg164JmvKu8u9iWNHM
# OAuth2 Proxy
OAUTH2_PROXY_HOSTNAME=127.0.0.1
OAUTH2_PROXY_PORT=4180

.env:

oauth2-proxy  | [2025/01/04 04:28:13] [provider.go:55] Performing OIDC Discovery...
oauth2-proxy  | [2025/01/04 04:28:13] [main.go:59] ERROR: Failed to initialise OAuth2 Proxy: error initialising provider: could not create provider data: error building OIDC ProviderVerifier: could not get verifier builder: error while discovery OIDC configuration: failed to discover OIDC configuration: error performing request: Get "http://keycloak:5001/realms/hapi-fhir-dev/.well-known/openid-configuration": dial tcp 172.18.0.4:5001: connect: connection refused
oauth2-proxy exited with code 1

I can:

curl http://127.0.0.1:5001/realms/hapi-fhir-dev/.well-known/openid-configuration

And:

{
    "issuer": "http://127.0.0.1:5001/realms/hapi-fhir-dev",
    "authorization_endpoint": "http://127.0.0.1:5001/realms/hapi-fhir-dev/protocol/openid-connect/auth",
    "token_endpoint": "http://127.0.0.1:5001/realms/hapi-fhir-dev/protocol/openid-connect/token",
    "introspection_endpoint": "http://127.0.0.1:5001/realms/hapi-fhir-dev/protocol/openid-connect/token/introspect",
    "userinfo_endpoint": "http://127.0.0.1:5001/realms/hapi-fhir-dev/protocol/openid-connect/userinfo",
    "end_session_endpoint": "http://127.0.0.1:5001/realms/hapi-fhir-dev/protocol/openid-connect/logout",
    "frontchannel_logout_session_supported": true,
    "frontchannel_logout_supported": true,
    "jwks_uri": "http://127.0.0.1:5001/realms/hapi-fhir-dev/protocol/openid-connect/certs",
    "check_session_iframe": "http://127.0.0.1:5001/realms/hapi-fhir-dev/protocol/openid-connect/login-status-iframe.html",

  ...

}

@Robinyo
Copy link
Author

Robinyo commented Jan 4, 2025

Success performing OIDC Discovery (using oidc provider):

oauth2-proxy  | [2025/01/04 05:26:57] [provider.go:55] Performing OIDC Discovery...
oauth2-proxy  | [2025/01/04 05:26:57] [proxy.go:89] mapping path "/" => upstream "http://hapi-fhir:8080/"
oauth2-proxy  | [2025/01/04 05:26:57] [oauthproxy.go:172] OAuthProxy configured for OpenID Connect Client ID: oauth2-proxy
oauth2-proxy  | [2025/01/04 05:26:57] [oauthproxy.go:178] Cookie settings: name:oauth2-proxy secure(https):false httponly:true expiry:10m0s domains: path:/ samesite:lax refresh:after 5m0s

Updated:

  keycloak:
    ...
    environment:
      KC_HOSTNAME: keycloak
    ports:
      - ${KEYCLOAK_PORT:-5001}:8080

  oauth2-proxy:
    ...
    environment:
      OAUTH2_PROXY_OIDC_ISSUER_URL: http://keycloak:8080/realms/hapi-fhir-dev

Note: 8080 not 5001.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants