From 051aa1764bd51460e71418f2b465866364a5929d Mon Sep 17 00:00:00 2001 From: Emmanuel Schmid Date: Thu, 15 Jan 2026 16:27:12 +0100 Subject: [PATCH] fix(oidc): Az single tenant handling via oidc_jwks_uri --- source/app/configuration.py | 1 + .../access_control/oidc_handler.py | 44 +++++++++++++------ 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/source/app/configuration.py b/source/app/configuration.py index fb00436b6..76367e3cd 100644 --- a/source/app/configuration.py +++ b/source/app/configuration.py @@ -470,6 +470,7 @@ class Config: OIDC_AUTH_ENDPOINT = config.load('OIDC', 'AUTH_ENDPOINT', fallback=None) OIDC_TOKEN_ENDPOINT = config.load('OIDC', 'TOKEN_ENDPOINT', fallback=None) OIDC_END_SESSION_ENDPOINT = config.load('OIDC', 'END_SESSION_ENDPOINT', fallback=None) + OIDC_JWKS_URI = config.load('OIDC', 'JWKS_URI', fallback=None) OIDC_SCOPES = config.load('OIDC', 'SCOPES', fallback="openid email profile") OIDC_MAPPING_USERNAME = config.load('OIDC', 'MAPPING_USERNAME', fallback='preferred_username') OIDC_MAPPING_EMAIL = config.load('OIDC', 'MAPPING_EMAIL', fallback='email') diff --git a/source/app/iris_engine/access_control/oidc_handler.py b/source/app/iris_engine/access_control/oidc_handler.py index 719fe2fa6..28098bbc9 100644 --- a/source/app/iris_engine/access_control/oidc_handler.py +++ b/source/app/iris_engine/access_control/oidc_handler.py @@ -25,24 +25,40 @@ def get_oidc_client(app) -> Client: client = Client(client_authn_method=CLIENT_AUTHN_METHOD) - # retrieve provider configuration dynamically from metadata - # or fall back to env vars + # Normalize issuer URL - strip trailing slash to prevent "Unknown Issuer" errors + issuer_url = app.config.get("OIDC_ISSUER_URL", "").rstrip('/') + client_id = app.config.get("OIDC_CLIENT_ID") + client_secret = app.config.get("OIDC_CLIENT_SECRET") + + # Check for explicit JWKS URI (e.g., Azure single-tenant with appid) + jwks_uri = app.config.get("OIDC_JWKS_URI") + try: - client.provider_config(app.config.get("OIDC_ISSUER_URL")) - except Exception as e: - app.logger.warning(f"Could not read OIDC metadata, using environment variables - error {e}") - op_info = ProviderConfigurationResponse( - issuer=app.config.get("OIDC_ISSUER_URL"), - authorization_endpoint=app.config.get("OIDC_AUTH_ENDPOINT"), - token_endpoint=app.config.get("OIDC_TOKEN_ENDPOINT"), - end_session_endpoint=app.config.get("OIDC_END_SESSION_ENDPOINT"), - ) + if jwks_uri: + # Manual configuration with explicit JWKS URI + app.logger.info(f"Using explicit JWKS URI: {jwks_uri}") - client.handle_provider_config(op_info, op_info['issuer']) + op_info = ProviderConfigurationResponse( + issuer=issuer_url, + authorization_endpoint=app.config.get("OIDC_AUTH_ENDPOINT"), + token_endpoint=app.config.get("OIDC_TOKEN_ENDPOINT"), + end_session_endpoint=app.config.get("OIDC_END_SESSION_ENDPOINT"), + jwks_uri=jwks_uri + ) + client.handle_provider_config(op_info, issuer_url) + else: + # Auto-discovery (standard OIDC flow) + app.logger.info("Using OIDC auto-discovery") + client.provider_config(issuer_url) + + except Exception as e: + app.logger.error(f"OIDC configuration failed: {e}") + raise + # Client Registration info = { - "client_id": app.config.get("OIDC_CLIENT_ID"), - "client_secret": app.config.get("OIDC_CLIENT_SECRET") + "client_id": client_id, + "client_secret": client_secret } client_reg = RegistrationResponse(**info) client.store_registration_info(client_reg)