potiuk opened a new pull request, #72225:
URL: https://github.com/apache/airflow/pull/72225
`get_user()` codes an explicit precedence — bearer, then OAuth2, then the
session cookie:
```python
if bearer_credentials and bearer_credentials.scheme.lower() == "bearer":
token_str = bearer_credentials.credentials
elif oauth_token:
token_str = oauth_token
else:
token_str = request.cookies.get(COOKIE_NAME_JWT_TOKEN)
```
That block was never reached when a session cookie was present.
`JWTRefreshMiddleware`
runs first, resolves a user from the `_token` cookie alone, and stamps it on
`request.state` together with the trust sentinel; `get_user()` returned that
cached
user up front, before looking at either explicit credential. The effective
order on
every core-API route was therefore **cookie over bearer** — the inverse of
what the
function reads as doing.
So a request carrying both a cookie and an explicit `Authorization: Bearer`
token ran
as the cookie's principal. The token the client deliberately presented was
ignored,
and the request was recorded in the audit log under the wrong identity.
## The change
The cached user is honoured only when the request carries no explicit
credential —
which is the case it exists for: a browser session whose token the
middleware has just
refreshed. When a bearer or OAuth2 token is present, that token is resolved
instead.
The trust-sentinel check is unchanged and still guards the cached-user path;
it has
simply moved inside the no-explicit-credential branch.
## Behaviour
| Request carries | Resolved as |
|---|---|
| cookie only | cookie principal (refreshed by the middleware, as before) |
| bearer only | bearer principal (as before) |
| OAuth2 only | OAuth2 principal (as before) |
| cookie **and** bearer | bearer principal (**changed** — was the cookie) |
| cookie **and** OAuth2 | OAuth2 principal (**changed** — was the cookie) |
Only the two mixed-credential rows change. A client that sends one
credential is
unaffected, and cookie-only browser sessions keep the refresh behaviour
intact.
## Tests
`test_get_user_explicit_credential_beats_cookie_user`, parametrised over
bearer and
OAuth2: a trusted cookie-derived user is stamped on `request.state` *and* an
explicit
credential is supplied; the explicit one must win. Both fail if the source
change is
reverted.
The existing `test_get_user_with_trusted_request_state` still passes
unmodified — it
supplies no explicit credential, so it exercises the path that was
deliberately kept.
140 passed across `core_api/test_security.py` and `auth/middlewares/`; ruff
clean.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]