Skip to content

Require logging in again when OIDC tokens can't be refreshed#22449

Merged
nuwang merged 24 commits intogalaxyproject:devfrom
AustralianBioCommons:oidc-require-refresh
Apr 30, 2026
Merged

Require logging in again when OIDC tokens can't be refreshed#22449
nuwang merged 24 commits intogalaxyproject:devfrom
AustralianBioCommons:oidc-require-refresh

Conversation

@marius-mather
Copy link
Copy Markdown
Contributor

We want to ensure users have a current, valid access token from the OIDC provider, so when attempting to refresh (due to access token expiry), log the user out and redirect to OIDC login. This is gated behind an oidc_require_refresh config flag.

How to test the changes?

(Select all options that apply)

  • I've included appropriate automated tests.
  • This is a refactoring of components with existing test coverage.
  • Instructions for manual testing are as follows:
    1. [add testing steps and prerequisites here if you didn't write automated tests covering all your changes]

License

  • I agree to license these and all my past contributions to the core galaxy codebase under the MIT license.

@github-actions github-actions Bot added area/testing area/auth Authentication and authorization labels Apr 10, 2026
@github-actions github-actions Bot added this to the 26.1 milestone Apr 10, 2026
@mvdbeek
Copy link
Copy Markdown
Member

mvdbeek commented Apr 14, 2026

@uwwint do you want to take a look at this ?

Copy link
Copy Markdown
Member

@nuwang nuwang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me except for one minor issue.

Comment thread lib/galaxy/webapps/base/webapp.py
@uwwint
Copy link
Copy Markdown
Contributor

uwwint commented Apr 15, 2026

@uwwint do you want to take a look at this ?

I was involved in this one @mvdbeek ;)

Comment thread lib/galaxy/authnz/managers.py Outdated
@mvdbeek
Copy link
Copy Markdown
Member

mvdbeek commented Apr 15, 2026

Code Review — Require logging in again when OIDC tokens can't be refreshed

Code Structure (type annotations & imports)

lib/galaxy/authnz/managers.py — typing gaps on new/touched signatures:

  • _reauth_required_from_refresh_exception(exc) — add exc: BaseException) -> bool
  • refresh_expiring_oidc_tokens_for_provider(self, trans, auth) — annotate trans and auth: model.UserAuthnzToken
  • refresh_expiring_oidc_tokens(self, trans, user=None) — annotate trans, user: Optional[model.User] = None

lib/galaxy/webapps/base/webapp.pyhandle_user_reauthentication missing -> None; trailing bare return is redundant.

lib/galaxy/config/init.py, test/unit/authnz/test_authnz.py — clean. Minor: the relative import from ..webapps.test_webapp_base reaches across test packages; consider moving CORSParsingMockConfig/StubGalaxyWebTransaction to a shared test utility.

Dependency Injection

No new DI violations. Both trans.app.config.oidc_require_refresh and self.app.authnz_manager accesses are consistent with the existing pattern in legacy GalaxyWebTransaction / AuthnzManager request-path code. No new Depends(), no new app.* property, no internal construction of collaborators. handle_user_reauthentication is a cohesive sibling of handle_user_logout.

Tests (mocking / patches)

Four/five new tests. The first two exercise real manager logic with a mocked backend; the last three stub the manager wholesale, which weakens them.

Concerns:

  1. Tests 3–5 replace AuthnzManager with MagicMock() — they effectively verify "webapp forwards the stubbed return value." Prefer the real AuthnzManager with a fake backend registered in config.
  2. patch.object(manager, "_get_authnz_backend", ...) patches a private method. Introduce a thin backend-resolver seam, or register a fake in oidc_backends_config so the real _get_authnz_backend finds it.
  3. patch("galaxy.webapps.base.webapp.url_for", ...) couples to an import detail — assert response.send_redirect was called with a location containing /authnz/oidc/login instead.
  4. Prefer state over interaction verification — drop backend.refresh.assert_called_once_with(trans, auth); the returned value already proves the call happened. Tests 4/5 model the right style (assert response.status, error_message).

Top recommendations

  1. Add annotations to the three signatures in managers.py and -> None on handle_user_reauthentication.
  2. Stop mocking AuthnzManager in the webapp tests; use the real manager with a fake backend.
  3. Remove the assert_called_once_with interaction checks in favor of state assertions.

Overall: small, focused change that follows surrounding patterns. Fixes are minor — primarily typing polish and test quality improvements.

@mvdbeek
Copy link
Copy Markdown
Member

mvdbeek commented Apr 21, 2026

The package unit test failures are real though.

@marius-mather
Copy link
Copy Markdown
Contributor Author

Thanks @mvdbeek - test failures should be fixed now

default: false
required: false
desc: |
Require a current OIDC session. Users will be redirected to OIDC login if refresh fails.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can only be enabled if all OIDC backends support refresh, right ? I think that's an important gotcha and maybe reason enough to push this into the backend instead ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mvdbeek Can you clarify what you meant by push this into the backend? But in any case, @marius-mather, perhaps a clarifying note indicating that all OIDC backends will need to support refresh would be useful?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Push that setting into the OIDC backend config

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mvdbeek the refresh config has been pushed down to the individual provider level now

Copy link
Copy Markdown
Member

@nuwang nuwang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great to me @marius-mather!

@nuwang nuwang merged commit 21408ef into galaxyproject:dev Apr 30, 2026
66 of 70 checks passed
@github-project-automation github-project-automation Bot moved this from Needs Review to Done in Galaxy Dev - weeklies Apr 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/auth Authentication and authorization area/testing kind/enhancement

Projects

Development

Successfully merging this pull request may close these issues.

4 participants