microsoft-authentication-library-for-js: Front-channel logout doesn't work as expected
Core Library
MSAL.js (@azure/msal-browser)
Core Library Version
3.3.0
Wrapper Library
MSAL React (@azure/msal-react)
Wrapper Library Version
2.0.5
Public or Confidential Client?
Public
Description
As stated per docs we should be able to logout a user from all authenticated sessions of a specific app(s) with Azure AD. However, after following all required steps, only the app that initiated the logout request, logged out correctly.
When inspecting the chrome devtools I do see the GET request to the other apps that need to be logged out. As stated per docs this is being done by loading an invisible iframe. So that works as expected as far as I am concerned. The console.log in my Logout.jsx is also being called correctly. However, no sign out appeared.
Here are the settings for my app registration in Azure AD
Error Message
No error shown. But authenticated session in other apps remains in place. Which shouldn’t happen. However, when I load an iframe myself from app-1 itself for example it does remove the session. When the iframe is loaded from app-2 the session isn’t removed.
App 1 is hosted on https://dbm.localhost:3001 App 2 is hosted on https://localhost:3000
Msal Logs
No response
MSAL Configuration
export const msalConfig = {
auth: {
clientId: "hidden for security purposes", // This is the ONLY mandatory field that you need to supply.
redirectUri: "/", // You must register this URI on Azure Portal/App Registration. Defaults to window.location.origin
postLogoutRedirectUri: "/", // Indicates the page to navigate after logout.
clientCapabilities: ["CP1"], // this lets the resource owner know that this client is capable of handling claims challenge.
},
cache: {
cacheLocation: "localStorage", // sessionStorage has the same result
storeAuthStateInCookie: false, // Set this to "true" if you are having issues on IE11 or Edge
},
system: {
allowRedirectInIframe: true,
loggerOptions: {
loggerCallback: (level, message, containsPii) => {
if (containsPii) {
return;
}
switch (level) {
case LogLevel.Error:
console.error(message);
return;
case LogLevel.Info:
console.info(message);
return;
case LogLevel.Verbose:
console.debug(message);
return;
case LogLevel.Warning:
console.warn(message);
return;
}
},
},
},
};
Relevant Code Snippets
Here is the code of the Logout.jsx page that is included in the react-router as a route.
React, { useEffect } from "react";
import { useMsal } from "@azure/msal-react";
import { BrowserUtils } from "@azure/msal-browser";
export function Logout() {
const { instance } = useMsal();
useEffect(() => {
instance.logoutRedirect({
account: instance.getActiveAccount(),
onRedirectNavigate: () => !BrowserUtils.isInIframe(),
});
}, [instance]);
return <div>Logout</div>;
}
Reproduction Steps
- Login to app on https://app-1.localhost:3000
- Login to app on https://app-2.localhost:3001
- Logout from app on https://app-1.localhost:3000
- A GET request should happen to logout https://app-2.localhost:3001
Expected Behavior
It should call the https://app-2.localhost:3001/logout (called app-1 and app-2 for demo purposes) url and actually removing the session/localstorage authenticated session of the user.
This does work if you call the url manually. (https://localhost:3001/logout)
The code is being called in the iframe by Azure AD front-channel feature. However the localstorage/session storage isn’t cleared on the actual app that needs to be logged out as well. This implies to me that the browser is blocking this because of the same origin policy. I might be wrong but that’s just a thought that came up to my mind.
Identity Provider
Azure AD / MSA
Browsers Affected (Select all that apply)
Chrome
Regression
No response
Source
Internal (Microsoft)
About this issue
- Original URL
- State: closed
- Created 8 months ago
- Reactions: 1
- Comments: 16
Nope, Microsoft support takes ages to get back to my query. … Still no resolution. They even have said they don’t support such a feature.
So in terms of internal knowledge, it’s. a bit dissapointed…
That’s correct. I also can confirm this doesn’t work for session storage. @tnorling could you elaborate more on this?
Is this front-channel logout feature event meant for sessionStorage end of the day?
Just checked, for ‘sessionStorage’ disabling #third-party-storage-partitioning doesn’t seem to work at all
I am experiencing the same issue. app2’s front-channel logout URL is called but its local storage is not cleared. It seems to depend on the browser’s handling of cookies. My results after testing in different browsers:
If I am correct front-channel logout doesn’t seem to be useful anymore since browsers have and are becoming more strict.
I wonder if the iframe is being closed before your page has fully rendered and triggered the effect. I’d recommend trying a simple HTML page with no React or anything other than instantiating PublicClientApplication and invoking logoutRedirect.