fix(auth): preserve login redirects across tabs - #43606
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #43606 +/- ##
==========================================
+ Coverage 79.21% 79.24% +0.02%
==========================================
Files 2879 2880 +1
Lines 166040 166322 +282
Branches 38405 38471 +66
==========================================
+ Hits 131536 131808 +272
- Misses 32025 32027 +2
- Partials 2479 2487 +8
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Code Review Agent Run #6f75cbActionable Suggestions - 0Review Details
Bito Usage GuideCommands Type the following command in the pull request comment and save the comment.
Refer to the documentation for additional commands. Configuration This repository uses Documentation & Help |
|
hey @aminghadersohi, thanks for working on this! I'm just curious if we really need the marker? It isn't bound to a session or user, so an attacker can mint one with an unauthenticated Also, the marker is minted when the login page loads, so other tabs that are stale for a longer time could be impacted. |
|
Good point — I agree that signing did not provide meaningful provenance here because the anonymous endpoint would mint a token for any safe same-host destination, and the expiry worked against the stale-tab case. I simplified this to a plain |
✅ Deploy Preview for superset-docs-preview ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Code Review Agent Run #212781Actionable Suggestions - 0Additional Suggestions - 2
Review Details
Bito Usage GuideCommands Type the following command in the pull request comment and save the comment.
Refer to the documentation for additional commands. Configuration This repository uses Documentation & Help |
|
thanks, @aminghadersohi 🙏 I think this looks better. Just one thought here: as far as I can tell there are 3 problems here and none of them are really in Superset:
If 2 was fixed upstream so authenticated users get a On 3, the SPA posts credentials to It might be better if we:
if g.user is not None and g.user.is_authenticated:
return redirect(self._safe_next_url() or self.appbuilder.get_url_for_index)What do you think? Curious if @dpgaspar has an thoughts here as well. |
|
Thanks, Vitor — I confirmed the three behaviors upstream. I split the work as suggested:
Both are linked to Shortcut story 97504. I’m leaving this Superset PR open as a draft until the upstream fixes are accepted and there is a release we can bump to; at that point this can be replaced by the much smaller dependency-bump/Superset change you outlined. |
|
Thanks again, @Vitor-Avila, for digging into this and identifying that the underlying problems belong in Flask-AppBuilder. Your suggested direction is cleaner than carrying a Superset-specific marker and redirect workaround. I’ve split the work upstream:
I’m closing this PR without merging because those upstream fixes supersede its approach. Once the FAB changes are released, we can update the FAB dependency in Superset and add the minimal Superset-side change/regression coverage needed for the original multi-tab scenario. Thank you for steering this toward the right layer 🙏 |
SUMMARY
When several tabs reach
/login/?next=...after a session expires, completing login in one tab authenticates the shared browser session. Refreshing another tab then takes the login view's already-authenticated branch, which previously discardednextand sent the user to the index.This adds
login_redirect=1while the request is known to be anonymous. An already-authenticated login request honorsnextonly when that flag is present. Unmarked authenticated login requests still go to the index, preserving the existing protection against redirect loops when an authenticated user is sent to login after a permission denial.The flag grants no authorization and is intentionally not a security token. Destinations still pass Flask-AppBuilder's safe-redirect validation; backslash-containing destinations are rejected so browser and server URL parsing cannot disagree.
BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
Not applicable; this changes server-side redirect behavior without changing the UI.
TESTING INSTRUCTIONS
Automated:
PYTHONPATH="$PWD/superset-core/src:$PWD" pytest -q tests/unit_tests/views/test_auth.py uvx pre-commit run --files superset/views/auth.py tests/unit_tests/views/test_auth.pyThe regression suite covers:
nextwhile anonymous;SCRIPT_NAME/application-root deployments.Manual:
PERMANENT_SESSION_LIFETIME.ADDITIONAL INFORMATION