See this comment: #3990 (comment)
@rockylhotka - this is regarding the SetUser issue we discussed yesterday on discord. I cannot use a .cshtml file as suggested.
After sleeping on it, I realized this is related to the cookies shared across browser tabs issue. I should not have that forced upon my app by requiring HttpContext. Let me try to explain as briefly as possible:
Our large Blazor app created in .net 6 and recently upgraded to .net 8 is 100% SIR only (required as will be seen). We have no context switching beyond the requisite one at startup when a circuit starts in app.razor.
A static UserCircuitTracker service keeps track of all circuits, their associated user, and whether a circuit is a root or child. A root login or circuit is a tab/circuit where a user performs a unique login. Whereas, a child tab/circuit is one that is opened from a root (think of it like your original tab opens a popup or popout tab). No cookies are involved. Nothing is shared across browser tabs.
Because of this, our app can offer some very powerful features:
- I login to the app - this becomes "Tab1/Root1"
- I open a new tab and login again - this becomes "Tab2/Root2" (totally independent of "Tab1/Root1").
The UserCircuitTracker knows the user is logged in twice but that is not relevant to this discussion
- In Tab1/Root1 I open a child tab/window - this becomes "Tab3/Root1->Child1". When it opens it has it's own circuit and I am logged in because it knows it is a child of the Root1. The
UserCircuitTracker takes care of these associations.
- Services like Menu and Login/Logout know to treat child circuits special (hiding the main menu and logout button etc). The "back button" in a child tab closes the window instead of navigating back.
- If user leaves open "Tab3/Root1->Child1" and switches back to "Tab1/Root1" and then clicks Logoff, the system prompts the user "ATTENTION: You have child windows open. Do you want to force close all of them? Yes or Cancel Logoff"
- If user chooses "Cancel" then nothing happens and they can go deal with the child tab they left open.
- If user chooses "Yes" then all child tabs of Tab1/Root1 get immediately closed (via javascript interop) and then finally Tab1/Root1 gets logged off (sent to logoff.cshtml).
This is a very powerful feature but it requires SIR only. It breaks if I were to start using cookies or SSR or WASM (which I obviously will not do)
- Child pages closing via js clears their circuit scoped memory
- Logoff page going to .cshtml clears its scoped circuit and memory. No worry about clearing cookies or sessions.
- The
UserCircuitTracker simply watches for OnCircuitClosedAsync events to do housekeeping on the static memory space. (currently bound to a single 'non-farm' scenario - which we are OK with).
With that as the back-drop, I come to the point how <= 8.1.0 AppContextManager allowed me to SetUser. IMHO this is a completely valid scenario. It rightly only sets the ClaimsPrincipal in memory and not in HTTPContext. In my circuits, per all the MS docs, I don't use HTTPContext beyond a read-only list of values (e.g. header values) like for knowing the user's preferred culture code. I grab those values at circuit startup time.
So now in .NET 8 here comes Microsoft saying you shouldn't set User outside of a component. Why? To accommodate our cool new feature we added (forced upon you) called context switching between WASM / SIR / SSR etc. Well what if I don't want that? Too bad. It's the new norm. The new "best practice" causes me to lose a core and cool feature.
So long story long. I need the ability restored to SetUser in memory to accommodate this SIR in-memory only app scenario. I argue this is not bad behavior. given this context. Yes I can presumably copy the old ApplicationContextManagerInMemory and get the old behavior back, but now I face the risk of getting out of sync with CSLA upgrades in future.
My ask is - can I have this added back into the context manager perhaps gated behind a configuration option for SIR only scenarios or something like that?
See this comment: #3990 (comment)
@rockylhotka - this is regarding the
SetUserissue we discussed yesterday on discord. I cannot use a .cshtml file as suggested.After sleeping on it, I realized this is related to the cookies shared across browser tabs issue. I should not have that forced upon my app by requiring HttpContext. Let me try to explain as briefly as possible:
Our large Blazor app created in .net 6 and recently upgraded to .net 8 is 100% SIR only (required as will be seen). We have no context switching beyond the requisite one at startup when a circuit starts in app.razor.
A static
UserCircuitTrackerservice keeps track of all circuits, their associated user, and whether a circuit is a root or child. A root login or circuit is a tab/circuit where a user performs a unique login. Whereas, a child tab/circuit is one that is opened from a root (think of it like your original tab opens a popup or popout tab). No cookies are involved. Nothing is shared across browser tabs.Because of this, our app can offer some very powerful features:
The
UserCircuitTrackerknows the user is logged in twice but that is not relevant to this discussionUserCircuitTrackertakes care of these associations.This is a very powerful feature but it requires SIR only. It breaks if I were to start using cookies or SSR or WASM (which I obviously will not do)
UserCircuitTrackersimply watches forOnCircuitClosedAsyncevents to do housekeeping on the static memory space. (currently bound to a single 'non-farm' scenario - which we are OK with).With that as the back-drop, I come to the point how <= 8.1.0 AppContextManager allowed me to SetUser. IMHO this is a completely valid scenario. It rightly only sets the ClaimsPrincipal in memory and not in HTTPContext. In my circuits, per all the MS docs, I don't use HTTPContext beyond a read-only list of values (e.g. header values) like for knowing the user's preferred culture code. I grab those values at circuit startup time.
So now in .NET 8 here comes Microsoft saying you shouldn't set User outside of a component. Why? To accommodate our cool new feature we added (forced upon you) called context switching between WASM / SIR / SSR etc. Well what if I don't want that? Too bad. It's the new norm. The new "best practice" causes me to lose a core and cool feature.
So long story long. I need the ability restored to SetUser in memory to accommodate this SIR in-memory only app scenario. I argue this is not bad behavior. given this context. Yes I can presumably copy the old
ApplicationContextManagerInMemoryand get the old behavior back, but now I face the risk of getting out of sync with CSLA upgrades in future.My ask is - can I have this added back into the context manager perhaps gated behind a configuration option for SIR only scenarios or something like that?