GitHub user brouberol added a comment to the discussion: Airflow API 
authentication using Kerberos is not working from the version 2.8.0

Ok. so here's what I found. The default `auth_manager` is 
`airflow.providers.fab.auth_manager.fab_auth_manager.FabAuthManager`, which has 
a 
[`get_user`](https://github.com/apache/airflow/blob/baf2b3cb4453d44ff00598a3b0c42d432a7203f9/providers/src/airflow/providers/fab/auth_manager/fab_auth_manager.py#L185-L189)
 method relying on 
[`flask-login`](https://github.com/maxcountryman/flask-login/)'s 
[`current_user`](https://github.com/maxcountryman/flask-login/blob/main/src/flask_login/utils.py#L25)
 to get the currently logged in user [from the 
session](https://github.com/maxcountryman/flask-login/blob/main/src/flask_login/login_manager.py#L320-L323).

As it stands, it seems that Kerberos authentication _cannot_ work with the 
stable API, as the `kerberos_auth` authentication backend stores the user 
associated with the Kerberos token [in 
`g`](https://github.com/brouberol/airflow/blob/main/providers/src/airflow/providers/fab/auth_manager/api/auth/backend/kerberos_auth.py#L136),
 not in the session.

So, what I've done to make the airflow stable API work with Kerberos 
authentication is define a custom auth manager:

```python
# custom_manager.py
from airflow.providers.fab.auth_manager.fab_auth_manager import FabAuthManager
from airflow.providers.fab.auth_manager.models import User


class CustomAuthManager(FabAuthManager):
    """An authentication manager supporting both session and Keberos 
authentication for the Airflow stable API."""

    def get_user(self) -> User:
        """Attempt to find the current user in g.user, as defined by the 
kerberos authentication backend.

        If no such user is found, return the `current_user` local proxy object, 
linked to the user session.

        """
        from flask_login import current_user
        from flask import g

        # If a user has gone through the Kerberos dance, the kerberos 
authentication manager
        # has linked it with a User model, stored in g.user, and not the 
session.
        if (
            current_user.is_anonymous
            and getattr(g, "user", None) is not None
            and not g.user.is_anonymous
        ):
            return g.user
        return super().get_user()
```   

and defined the following `airflow.cfg` config:

```
[core]
auth_manager = path.to.custom_auth_manager.CustomAuthManager
```

And with that, I was able to query the stable API with a kerberos token:
```
brouberol@stat1008:~$ curl --negotiate -u: -s --service-name airflow 
https://airflow-test-k8s.discovery.wmnet:30443/api/v1/pools
{
  "pools": [
    {
      "deferred_slots": 0,
      "description": "Default pool",
      "include_deferred": false,
      "name": "default_pool",
      "occupied_slots": 0,
      "open_slots": 128,
      "queued_slots": 0,
      "running_slots": 0,
      "scheduled_slots": 0,
      "slots": 128
    }
  ],
  "total_entries": 1
}
```

GitHub link: 
https://github.com/apache/airflow/discussions/39683#discussioncomment-11098032

----
This is an automatically sent email for [email protected].
To unsubscribe, please send an email to: [email protected]

Reply via email to