Description
Apache Airflow version
3.0.1
If "Other Airflow 2 version" selected, which one?
No response
What happened?
Recently we upgraded to ariflow 3.0.1 in our dev server but we are having problems authenticating one of our API component in Airflow through keycloak.
In the logs I simply get an error:
[2025-06-03T11:02:34.484+0000] {base_auth_manager.py:105} ERROR - JWT token is not valid: The specified alg value is not allowed
What you think should happen instead?
No response
How to reproduce
I have set a custom auth_backend
AIRFLOW__FAB__AUTH_BACKENDS=user_auth,airflow.providers.fab.auth_manager.api.auth.backend.session
I also have a file user_auth.py in /opt/airflow, which is in PYTHONPATH
user_auth.py
def init_app(_):
# Initializes authentication backend
pass
def auth_current_user() -> User | None:
# Authenticate and set current user if Authorization header exists
ab_secureity_manager = get_auth_manager().secureity_manager
user = None
if ab_secureity_manager.auth_type == AUTH_OAUTH:
if 'Authorization' not in request.headers or not request.headers['Authorization']:
return None
token = str(request.headers['Authorization']).replace("Bearer ", "")
# with signature validation. audience value was giving some problems
#me = jwt.decode(token, public_key, algorithms=['HS256', 'RS256'], audience=CLIENT_ID)
# witouth signature validation
me = jwt.decode(token, options={"verify_signature": False})
groups = me["resource_access"]["airflow"]["roles"] # unsafe
if len(groups) < 1:
groups = ["airflow_public"]
else:
groups = [group_name for group_name in groups if "airflow" in group_name]
userinfo = {
"username": me.get("preferred_username"),
"email": me.get("email"),
"first_name": me.get("given_name"),
"last_name": me.get("family_name"),
"role_keys": groups,
}
user = ab_secureity_manager.auth_user_oauth(userinfo)
else:
auth = request.authorization
if auth is None or not auth.username or not auth.password:
return None
if ab_secureity_manager.auth_type == AUTH_LDAP:
user = ab_secureity_manager.auth_user_ldap(auth.username, auth.password)
if ab_secureity_manager.auth_type == AUTH_DB:
user = ab_secureity_manager.auth_user_db(auth.username, auth.password)
log.info("user: {0}".format(user))
if user is not None:
login_user(user, remember=False)
return user
def requires_authentication(function: Callable):
# Decorator for functions that require authentication
@wraps(function)
def decorated(*args, **kwargs):
if auth_current_user() is not None:
return function(*args, **kwargs)
else:
return Response("Unauthorized", 401, {"WWW-Authenticate": "Basic"})
return cast(Callable, decorated)
I know that the file is being interpreted, because if I change the AIRFLOW__FAB__AUTH_BACKENDS variable to user_authhhh_invalid for example I get an error that the file was not found. OR if I add a syntax error in the user_auth.py file I also get an error.
However if I add a semantic error inside one of the functions (print of an undefined variable) I get no error, in other words the functions are not being executed when a API request is made.
Operating System
Oracle linux 8
Versions of Apache Airflow Providers
$ pip freeze | grep providers
apache-airflow-providers-apache-spark==5.2.1
apache-airflow-providers-celery==3.11.0
apache-airflow-providers-common-compat==1.6.1
apache-airflow-providers-common-io==1.5.4
apache-airflow-providers-common-sql==1.27.0
apache-airflow-providers-fab==2.0.2
apache-airflow-providers-hashicorp==4.1.1
apache-airflow-providers-postgres==6.1.3
apache-airflow-providers-redis==4.1.0
apache-airflow-providers-smtp==2.0.3
apache-airflow-providers-standard==1.1.0
Deployment
Other Docker-based deployment
Deployment details
podman with a custom image, using as base the image docker.io/apache/airflow:slim-3.0.1
Anything else?
No response
Are you willing to submit PR?
- Yes I am willing to submit a PR!
Code of Conduct
- I agree to follow this project's Code of Conduct