Skip to content

Using flow executor with JWT is broken #15747

@lemoer

Description

@lemoer

Describe the bug

I am currently trying to use the flow executor with a JWT.

This doesn't seem to work. The authentication is always rejected in FlowPlaner._check_authentication() here:

and not request.user.is_authenticated

To Reproduce
Steps to reproduce the behavior:

  1. Use oauth to obtain a JWT
  2. Request GET /api/v3/flows/executor/:slug

Expected behavior

I expect the flow to recognize the JWT authentication.

Logs

Request to /api/v3/flows/executor/default-user-settings-flow/:

{"event":"tracing request to backend","headers":{"Authorization":["Bearer eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwia2lkIjoiZDRmZTQxNmY0Y2FiZmY3ZjM0MWNlNmQ1Y2JiOTA1YzIiLCJ0eXAiOiJKV0UifQ.R7IJ9rlWhgOsWfge1dSdSzOWl37t7_BKHXyfmOByqaJd6gE6rCFUZrQSSezELgiwqv4QhLp2YVyTUVThBTSXWOa36ZVtPV3Blb7relhKBINCMzWK0teBzs5FvrM_zDJt0PLgmpXUhyU0pRp0VSJUYRHOj_JYvnMBNs0tcUPMOVzPe2tR4e0_Jbq5PccfaQI_6XPFeApPvkadLuieb6IROEw3nGmztno24DcBbcJCGaC7zFLz1s3BCywV2DJiVFi3ESxnIDQLbDCK3v-9JH8UULh63I-bE1fYHMRibx-8PsgFKps425mvzJA0VTx5CIzu70RLq4EnADMbzO9lAPQneQ.2DqPzIrk7XNW3PzXBFHL9g.v39CkMoRSpx4BsE4nZHfV8zIQmA56LhXpjDow1AO7bUQGQTes_UofYO67gmOuqNm_4TIng6wGUbHlb9VVKMchZYU-APDgi9kPvMmUMcUihDdjWqSqlDiXliBnnciQo1EilB7T27h-8OI-F_apvM_vILFfW2HcRyU2DU-IssnUwT-pDoyBUubkjhnDNMt4NbbfZy8xZCYKxY2bbzQFTM8LgYQdnDnuC_tf2dMag0j9ZGdKXEl7FNGu1Jpduw8E83WPDJMRgSjavkAcoHNAIekZWvEy0gSxDbQ1vrNnbxFytyZTwqLHKCRZ5BYs5gChxJtDFtawKmCyO1DzM-5VZg3btzshzm46dZVw5SNYwrePDmV7n979UTUzwQrHG1FIWZQNjlleNmAq6tN-osxkBMDtbmQ9oN-TGZFSn1eB1RZ3HeHp8sFvZ9qwnrv2E0wcP080N6TnOKCMRFdkHfKbS4MZgIysrmjd22k19NO4rlPrmDCOLs58POaSPLczuAeO_TBuzMf2e0QD_z4tQgjKUy_1ik2dtbp-mT5GJAP_VMXhZ_2De4lw8kogKmkvfQn1aSBq6YpNM1QqpNEpoBs2AtTZYiLDQcC1Bu_THJXukNy9wT5WtP--N7nuLQPX3afQmc3jtJC86T1IwWzUIXoANGEuAd08T4xEgrFiM3RnbO3Tylgeq4k1L9OzmeiN8AKV7N3Ew3q0ZOIXJoTKbZCw0UyDb1-GdGyR-6uaUkUKtzmILvTZvQG2mhS1gjXqAdHqUcDTJrVVzDKOFcgBOsFAQPpQF0VOxSnRx4wmDYsJ-MKG7ibXx5V4C1LKwcQsbYzgwx8OFSL-mk2fyJedS8WZ8_Bj8dVQZytjn8TzGdpHSh07rNUyzBSbVekztwS_wxc6_jAro9YTEtleJKa-2rt2q6TISi7rVoJMWW7T4x-NWkG8yHkHuvqgA6auY--mc-etfoZqD0Xa1Dcsg1KQFClAdPaT_iUYTrvI_d7JGc2i2h6mApusdOf7YIvJjm7SzJUAjJKAZOpeF2eeHYNbg1J78GnbmzYw6XNTbqWvAGFqUwToR6qpE_WoSnYKn2lrYKRgIacWoswFvJBSxBp8E-UR8il-4B95LVbreFs_8ZmVz1xkTB7Ovxs54B_BonNVw4fBGDhhxgO2ACBWTMQvnpoqd-EyOUt6WtShS9p3y-AoQ4Ag6gZVnp06FE0ViuNEgNKNAim827ANumPF2JU3L9EnuW9upkUSbTikjCdyNKeCZhvUkk2O5faqYwkX6Nz5aQ--puQ-ETjvaZ4ciVznc8lg-BnY8jM67Cv97f3e_7-d-QdbJ_59yn_VrLK1glNtSNJ8uDDwIXSzLAnpSjA3esOkB-BwGC05397WkW2AGPEcKEPCflhjtNbgVS1vv9Uhw-2n53zPudFUzV-3RTyQSe1NFihBJTg0b63E8KXEby7k_JCwTpoIASwKZOIN413LMYW-rXbv-uAAWs6QWVNK5ArW6WD10sHN6dmiDTRLwlyRCZ5AMrk50GYAMv2U3GuHEND5fTt8K7e2cr2HJnDjFVe4GfBOrzfYda5L5EBJ8eo_EhO1x5BhbqFyTbWq58xOl3biUGUMK2eTbJxsG0zzAF4uosjDA5WDJBjrePkumbm3z4nziDsQ174CjAMxX-_ScEGCPYu_JQmFrECGT6f6IEVb2GrWMhxRspvM-u9xvXx6KhKicWuVbwpCOUsajQLKYgR_l_jWrLBb_V3evzjFjGYYMDo87aviSeIZ57-ZU8h4rX1hE4SldTuAKTQWcmj7LIe8vMmUtgOwU8FudpQh6dY9fAMrUyoaZjPamIqOvzS2Aykhnuf0GKYJBXjfmlohWuNQ-bN.Hs5xV3QDhi12M77ezrxVyYNpsNEhsKgvoGNz60Y_j38"],"Content-Length":["181"],"Content-Type":["application/json; charset=utf-8"],"User-Agent":["Dart/3.8 (dart:io)"],"X-Forwarded-For":["185.104.138.45"],"X-Forwarded-Proto":["https"]},"level":"trace","logger":"authentik.router","timestamp":"2025-06-22T19:00:54Z","url":"http://localhost:8000/api/v3/flows/executor/default-user-settings-flow/"}
{"auth_via": "unauthenticated", "domain_url": "auth.leinelab.org", "event": "f(exec): No active Plan found, initiating planner", "flow_slug": "default-user-settings-flow", "host": "auth.leinelab.org", "level": "debug", "logger": "authentik.flows.views.executor", "pid": 78, "request_id": "69d8065b0c2d42ccae287aee46a9d2e6", "schema_name": "public", "timestamp": "2025-06-22T19:00:54.994845"}
{"auth_via": "unauthenticated", "domain_url": "auth.leinelab.org", "event": "f(plan): starting planning process", "flow_slug": "default-user-settings-flow", "host": "auth.leinelab.org", "level": "debug", "logger": "authentik.flows.planner", "pid": 78, "request_id": "69d8065b0c2d42ccae287aee46a9d2e6", "schema_name": "public", "timestamp": "2025-06-22T19:00:54.996165"}
{"auth_via": "unauthenticated", "domain_url": "auth.leinelab.org", "event": "f(exec): Flow not applicable to current user", "exc": "FlowNonApplicableException()", "flow_slug": "default-user-settings-flow", "host": "auth.leinelab.org", "level": "warning", "logger": "authentik.flows.views.executor", "pid": 78, "request_id": "69d8065b0c2d42ccae287aee46a9d2e6", "schema_name": "public", "timestamp": "2025-06-22T19:00:54.996805"}
{"auth_via": "unauthenticated", "domain_url": "auth.leinelab.org", "event": "f(exec): Stage invalid", "flow_slug": "default-user-settings-flow", "host": "auth.leinelab.org", "level": "debug", "logger": "authentik.flows.views.executor", "pid": 78, "request_id": "69d8065b0c2d42ccae287aee46a9d2e6", "schema_name": "public", "timestamp": "2025-06-22T19:00:54.997318"}
{"auth_via": "unauthenticated", "domain_url": "auth.leinelab.org", "event": "f(exec): cleaning up", "flow_slug": "default-user-settings-flow", "host": "auth.leinelab.org", "level": "debug", "logger": "authentik.flows.views.executor", "pid": 78, "request_id": "69d8065b0c2d42ccae287aee46a9d2e6", "schema_name": "public", "timestamp": "2025-06-22T19:00:54.997586"}
{"auth_via": "unauthenticated", "domain_url": "auth.leinelab.org", "event": "/api/v3/flows/executor/default-user-settings-flow/", "host": "auth.leinelab.org", "level": "info", "logger": "authentik.asgi", "method": "POST", "pid": 78, "remote": "185.104.138.45", "request_id": "69d8065b0c2d42ccae287aee46a9d2e6", "runtime": 67, "schema_name": "public", "scheme": "https", "status": 200, "timestamp": "2025-06-22T19:00:55.026576", "user": "", "user_agent": "Dart/3.8 (dart:io)"}

Request to /api/v3/core/users/me with the same bearer token works:

{"event":"tracing request to backend","headers":{"Authorization":["Bearer eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwia2lkIjoiZDRmZTQxNmY0Y2FiZmY3ZjM0MWNlNmQ1Y2JiOTA1YzIiLCJ0eXAiOiJKV0UifQ.R7IJ9rlWhgOsWfge1dSdSzOWl37t7_BKHXyfmOByqaJd6gE6rCFUZrQSSezELgiwqv4QhLp2YVyTUVThBTSXWOa36ZVtPV3Blb7relhKBINCMzWK0teBzs5FvrM_zDJt0PLgmpXUhyU0pRp0VSJUYRHOj_JYvnMBNs0tcUPMOVzPe2tR4e0_Jbq5PccfaQI_6XPFeApPvkadLuieb6IROEw3nGmztno24DcBbcJCGaC7zFLz1s3BCywV2DJiVFi3ESxnIDQLbDCK3v-9JH8UULh63I-bE1fYHMRibx-8PsgFKps425mvzJA0VTx5CIzu70RLq4EnADMbzO9lAPQneQ.2DqPzIrk7XNW3PzXBFHL9g.v39CkMoRSpx4BsE4nZHfV8zIQmA56LhXpjDow1AO7bUQGQTes_UofYO67gmOuqNm_4TIng6wGUbHlb9VVKMchZYU-APDgi9kPvMmUMcUihDdjWqSqlDiXliBnnciQo1EilB7T27h-8OI-F_apvM_vILFfW2HcRyU2DU-IssnUwT-pDoyBUubkjhnDNMt4NbbfZy8xZCYKxY2bbzQFTM8LgYQdnDnuC_tf2dMag0j9ZGdKXEl7FNGu1Jpduw8E83WPDJMRgSjavkAcoHNAIekZWvEy0gSxDbQ1vrNnbxFytyZTwqLHKCRZ5BYs5gChxJtDFtawKmCyO1DzM-5VZg3btzshzm46dZVw5SNYwrePDmV7n979UTUzwQrHG1FIWZQNjlleNmAq6tN-osxkBMDtbmQ9oN-TGZFSn1eB1RZ3HeHp8sFvZ9qwnrv2E0wcP080N6TnOKCMRFdkHfKbS4MZgIysrmjd22k19NO4rlPrmDCOLs58POaSPLczuAeO_TBuzMf2e0QD_z4tQgjKUy_1ik2dtbp-mT5GJAP_VMXhZ_2De4lw8kogKmkvfQn1aSBq6YpNM1QqpNEpoBs2AtTZYiLDQcC1Bu_THJXukNy9wT5WtP--N7nuLQPX3afQmc3jtJC86T1IwWzUIXoANGEuAd08T4xEgrFiM3RnbO3Tylgeq4k1L9OzmeiN8AKV7N3Ew3q0ZOIXJoTKbZCw0UyDb1-GdGyR-6uaUkUKtzmILvTZvQG2mhS1gjXqAdHqUcDTJrVVzDKOFcgBOsFAQPpQF0VOxSnRx4wmDYsJ-MKG7ibXx5V4C1LKwcQsbYzgwx8OFSL-mk2fyJedS8WZ8_Bj8dVQZytjn8TzGdpHSh07rNUyzBSbVekztwS_wxc6_jAro9YTEtleJKa-2rt2q6TISi7rVoJMWW7T4x-NWkG8yHkHuvqgA6auY--mc-etfoZqD0Xa1Dcsg1KQFClAdPaT_iUYTrvI_d7JGc2i2h6mApusdOf7YIvJjm7SzJUAjJKAZOpeF2eeHYNbg1J78GnbmzYw6XNTbqWvAGFqUwToR6qpE_WoSnYKn2lrYKRgIacWoswFvJBSxBp8E-UR8il-4B95LVbreFs_8ZmVz1xkTB7Ovxs54B_BonNVw4fBGDhhxgO2ACBWTMQvnpoqd-EyOUt6WtShS9p3y-AoQ4Ag6gZVnp06FE0ViuNEgNKNAim827ANumPF2JU3L9EnuW9upkUSbTikjCdyNKeCZhvUkk2O5faqYwkX6Nz5aQ--puQ-ETjvaZ4ciVznc8lg-BnY8jM67Cv97f3e_7-d-QdbJ_59yn_VrLK1glNtSNJ8uDDwIXSzLAnpSjA3esOkB-BwGC05397WkW2AGPEcKEPCflhjtNbgVS1vv9Uhw-2n53zPudFUzV-3RTyQSe1NFihBJTg0b63E8KXEby7k_JCwTpoIASwKZOIN413LMYW-rXbv-uAAWs6QWVNK5ArW6WD10sHN6dmiDTRLwlyRCZ5AMrk50GYAMv2U3GuHEND5fTt8K7e2cr2HJnDjFVe4GfBOrzfYda5L5EBJ8eo_EhO1x5BhbqFyTbWq58xOl3biUGUMK2eTbJxsG0zzAF4uosjDA5WDJBjrePkumbm3z4nziDsQ174CjAMxX-_ScEGCPYu_JQmFrECGT6f6IEVb2GrWMhxRspvM-u9xvXx6KhKicWuVbwpCOUsajQLKYgR_l_jWrLBb_V3evzjFjGYYMDo87aviSeIZ57-ZU8h4rX1hE4SldTuAKTQWcmj7LIe8vMmUtgOwU8FudpQh6dY9fAMrUyoaZjPamIqOvzS2Aykhnuf0GKYJBXjfmlohWuNQ-bN.Hs5xV3QDhi12M77ezrxVyYNpsNEhsKgvoGNz60Y_j38"],"User-Agent":["Dart/3.8 (dart:io)"],"X-Forwarded-For":["185.104.138.45"],"X-Forwarded-Proto":["https"]},"level":"trace","logger":"authentik.router","timestamp":"2025-06-22T19:00:52Z","url":"http://localhost:8000/api/v3/core/users/me/"}
{"auth_via": "jwt", "body": null, "domain_url": "auth.leinelab.org", "event": "HTTP request sent", "headers": "{'User-Agent': '[email protected]', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}", "host": "auth.leinelab.org", "level": "debug", "logger": "authentik.lib.utils.http", "method": "HEAD", "pid": 78, "request_id": "fed7c666c98e44cbb994403c5b64b5b3", "schema_name": "public", "timestamp": "2025-06-22T19:00:52.715857", "uid": "2718fcac-5705-4841-a284-efe62bc26ccb", "url": "https://www.gravatar.com/avatar/87aa1068d89b76f08da3c6c8708afd599e8b4d7037a30dfeedca366547634aec?size=158&rating=g&default=404"}
{"auth_via": "jwt", "body": "", "domain_url": "auth.leinelab.org", "event": "HTTP response received", "headers": "{'Server': 'nginx', 'Date': 'Sun, 22 Jun 2025 19:00:54 GMT', 'Content-Type': 'text/html; charset=utf-8', 'Content-Length': '13', 'Connection': 'keep-alive', 'Last-Modified': 'Wed, 11 Jan 1984 08:00:00 GMT', 'Link': '<https://gravatar.com/avatar/87aa1068d89b76f08da3c6c8708afd599e8b4d7037a30dfeedca366547634aec?size=158&rating=g&default=404>; rel=\"canonical\"', 'Access-Control-Allow-Origin': '*', 'ETag': '\"404\"', 'Cache-Control': 'max-age=300', 'Expires': 'Sun, 22 Jun 2025 19:05:54 GMT', 'Alt-Svc': 'h3=\":443\"; ma=86400', 'X-nc': 'HIT hhn 31', 'Server-Timing': 'a8c-cdn, dc;desc=hhn, cache;desc=HIT;dur=0.0'}", "host": "auth.leinelab.org", "level": "debug", "logger": "authentik.lib.utils.http", "pid": 78, "request_id": "fed7c666c98e44cbb994403c5b64b5b3", "schema_name": "public", "status": 404, "timestamp": "2025-06-22T19:00:54.503184", "uid": "2718fcac-5705-4841-a284-efe62bc26ccb"}
{"auth_via": "jwt", "domain_url": "auth.leinelab.org", "event": "/api/v3/core/users/me/", "host": "auth.leinelab.org", "level": "info", "logger": "authentik.asgi", "method": "GET", "pid": 78, "remote": "185.104.138.45", "request_id": "fed7c666c98e44cbb994403c5b64b5b3", "runtime": 2075, "schema_name": "public", "scheme": "https", "status": 200, "timestamp": "2025-06-22T19:00:54.627723", "user": "lemoer", "user_agent": "Dart/3.8 (dart:io)"}
{"cidr":"172.16.0.0/12","event":"Setting proxy headers","level":"trace","remoteAddr":"172.21.0.1","timestamp":"2025-06-22T19:00:54Z"}

Version and Deployment (please complete the following information):

  • authentik version: 2025.6.3
  • Deployment: docker-compose

Additional context

What I found out:

  • The JWT authentication is handled within APIView.dispatch() from the django-rest-framework.
  • The FlowExecutorView overrides APIView.dispatch() to implement the session handling required for flows.
  • At the end of FlowExecutorView.dispatch() the dispatch method from the superclass APIView.dispatch() is called:
    return super().dispatch(request)
    . So far, so good.
  • However, FlowPlanner._check_authentication() is already called before this happens. Call chain is: FlowExecutorView.dispatch() -> FlowExecutorView._initiate_plan() -> FlowPlanner.plan() -> FlowPlanner._check_authentication(). This starts already here:
    self.plan = self._initiate_plan()
  • This means that the request.user object in FlowPlanner._check_authentication() does not know about the JWT when accessing request.user, because the JWT is only handled later.

Workaround
I found a workaround by exchanging the JWT into a http session a priori to using the flow executor. I documented that in #15252. However, as I figured out later, this only seems to work as admin. I suspect, this is because the endpoint /api/v3/flows/instances/:slug/execute/ (that I use for the conversion from JWT -> http session) requires admin priviliges. However, this workaround is insufficient for me since I want to use the flow executor with regular users.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions