Skip to content

KeycloakAuthManager constructs invalid double-slash URLs when server_url has trailing slash (breaking Keycloak 26.4+) #61121

@ddovbii

Description

@ddovbii

Apache Airflow version

3.1.6

If "Other Airflow 3 version" selected, which one?

No response

What happened?

There is an architectural inconsistency in how the KeycloakAuthManager handles the server_url configuration, leading to a conflict when using Keycloak on a sub-path (e.g., KC_HTTP_RELATIVE_PATH=/auth).

The provider accesses Keycloak in two different ways using the same server_url config:

  1. Via python-keycloak library: This library uses urllib logic. If Keycloak is hosted at .../auth, the library requires a trailing slash (.../auth/) in the server_url. Without it, the library interprets the last segment (auth) as a file and strips it during path resolution (e.g., resulting in .../realms/... instead of .../auth/realms/...).
  2. Via manual construction (_get_token_url): The provider manually builds the token endpoint string:
return f"{server_url}/realms/{realm}/protocol/openid-connect/token"

The Conflict:
To satisfy python-keycloak, the user must configure server_url with a trailing slash (.../auth/). However, the manual concatenation in _get_token_url naively appends to this, resulting in a double-slash:
https://my-host.com/auth//realms/myrealm/...

The Impact:
While older Keycloak versions normalized this path, Keycloak 26.4.4+ (specifically RejectNonNormalizedPathFilter) strictly rejects non-normalized paths with HTTP 400 and the error:
{"error":"missingNormalization","error_description":"Request path not normalized"}

This leaves the user in a deadlock: removing the slash breaks the library; keeping the slash breaks the manual token check.

What you think should happen instead?

  • The KeycloakAuthManager should be consistent and robust in how it handles the server_url.
  • The provider should normalize the server_url before performing manual string concatenation. Specifically, in _get_token_url (and similar methods), it should strip any trailing slash to prevent the double-slash issue:
  • aleternatevily, refactor the provider to use the python-keycloak client for token acquisition instead of manually constructing the URL, ensuring unified logic for path resolution.

How to reproduce

  1. Deploy Keycloak (version 26.4.4 or newer) with KC_HTTP_RELATIVE_PATH=/auth.
  2. Configure the Airflow Keycloak provider with:
  • server_url: https://<keycloak-host>/auth/ (trailing slash required for python-keycloak).
  1. Trigger an action that requires KeycloakAuthManager to fetch a token.
  2. Observe the failure:
  • Airflow Logs: Token fetch fails.
  • Keycloak Logs: Returns HTTP 400 missingNormalization.

Operating System

Linux (Kubernetes Pods)

Versions of Apache Airflow Providers

apache-airflow-providers-keycloak 0.5.0

Deployment

Virtualenv installation

Deployment details

No response

Anything else?

No response

Are you willing to submit PR?

  • Yes I am willing to submit a PR!

Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions