ASP.NET MVC+SPA应用中OIDC addUserSignedOut事件未触发的原因及缺失环节咨询
addUserSignedOut Isn't Triggering in ASP.NET MVC + SPA & How to Fix It Let's break down why your event isn't firing and exactly what you're missing to get cross-app signout working like your pure Angular apps.
The Core Problem
Your ASP.NET MVC + SPA setup uses server-side Cookie authentication via HttpContext.GetOwinContext().Authentication.Challenge, which skips the key session management logic that oidc-client-js relies on to detect signouts.
In your pure Angular apps, signinRedirectCallback() automatically spins up a background iframe that silently pings your OIDC provider's check_session endpoint on a regular interval. This is how addUserSignedOut gets triggered when a user signs out from another app— the iframe detects the session has been invalidated and fires the event.
Your MVC setup never initializes this iframe-based monitoring because oidc-client-js isn't actually managing the user session on the frontend.
Missing Steps to Get the Event Working
1. Properly Initialize oidc.UserManager with Correct Config
First, make sure your SPA's UserManager settings match your OIDC provider and backend configuration. Critical settings include:
const settings = { authority: "your-oidc-provider-url", // e.g., your Identity Server endpoint client_id: "your-mvc-spa-client-id", // Must match backend client registration redirect_uri: `${window.location.origin}/signin-oidc`, // Match backend callback path post_logout_redirect_uri: `${window.location.origin}/logout-callback`, response_type: "code", scope: "openid profile email", monitorSession: true, // Enable session monitoring (default is true, but double-check) checkSessionInterval: 30000, // 30-second checks (adjust as needed) }; const um = new oidc.UserManager(settings);
2. Let oidc-client-js Take Over Session Management
Since your backend handles the initial login challenge, you need to sync the frontend with the existing session on page load:
// Run this when your SPA initializes um.getUser().then(async (user) => { if (!user) { // Try silent sign-in to grab the existing session from cookies try { await um.signinSilent(); } catch (err) { console.error("Silent sign-in failed (user may not be logged in):", err); } } }); // Now your signout event will fire when session changes um.events.addUserSignedOut(() => { console.log(`User Signed Out - Event triggered at ${new Date()}`); // Add your frontend cleanup logic here (e.g., redirect to logout, clear state) });
3. Update Backend OIDC Configuration
Ensure your backend's client registration allows silent sign-ins:
- Add
implicitto theAllowedGrantTypes(sincesigninSilentuses a variant of the implicit flow) - Include your SPA's origin in
AllowedCorsOriginsto prevent cross-origin issues with the monitoring iframe
Why This Works
By calling signinSilent() or ensuring getUser() returns a valid user, you kick off oidc-client-js's background iframe monitoring. This iframe will regularly check with your OIDC provider to see if the user's session has been invalidated (e.g., via a signout in another app). When it detects a change, the addUserSignedOut event will fire as expected.
内容的提问来源于stack exchange,提问作者Jeeva J

