Single sign-out (Front-channel logout URL) not working on client-side applications [Azure AD B2C]

Juliano Roberto da Silva Biffi 30 Reputation points
2025-04-07T13:51:22.64+00:00

Hello everyone! I'm trying to implement the single sign-out into a client-side applications (React JS + @azure/msal-react) and I'm facing with some issues.

Before, lets ilustrate. When the logout is performed the Azure AD B2C open an iframe and send a HTTP POST request into my application, and the application should invalidade the session.

The flow works fine into a server-side applications (your cookie SameSite should be None)enter image description here

When one of my applications performs a logout, the Front-channel logout URL is called. However, in my client-side application, when the iframe tries to perform the logout or clear the user's cookies, it doesn't work because the iframe cannot access the domain cookies, which are blocked due to third-party cookie restrictions, keeping the user session active.

The problem still persists if the user navigates between routes or refreshes the page, because the session remains active in the cache manager.

Solutions I’ve Tried (None Worked):

1. Skipping the server sign-out

I tried to implement a route, but it didn’t work.

WARNING: Skipping the server sign-out means the user's session will remain active on the server and can be signed back into your application without providing credentials again.


import 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>

    )

}

The code above was found here

2. I tried to catch the events

I tried adding an event callback expecting to receive a logout or account removal event. Apparently, it's only used for managing the current application between browser tabs.


msalInstance.addEventCallback((message: EventMessage) => {

    if (message.eventType === EventType.ACCOUNT_ADDED) {

        // Update UI with new account

    } else if (message.eventType === EventType.ACCOUNT_REMOVED) {

        // Update UI with account logged out

    } else if (message.eventType === EventType.ACTIVE_ACCOUNT_CHANGED) {

        const accountInfo = msalInstance.getActiveAccount();

        // Update UI with new active account info

    }

});

3. Propagate some message to main domain using postMessage() or BroadcastChannel

This didn’t work either :/

Final Considerations

I tried modifying my custom policies to intercept the logout flow but without success.

Some info about my implementation:

  • I use Custom Policies
  • My profiles are correctly configured according to SSO recommendation here and here
  • The full flow is working — all my applications can perform Single sign-in, and client-side applications can initiate Single sign-out.

If someone has solve the problem and can share the solution, I would be grateful ❤

Microsoft Security | Microsoft Entra | Microsoft Entra External ID
{count} vote

1 answer

Sort by: Most helpful
  1. Juliano Roberto da Silva Biffi 30 Reputation points
    2025-05-12T15:00:05.1433333+00:00

    There's no easy answer to this issue. The only way to solve it is by implementing the custom domain into the applications and Azure AD B2C. This issue is also known by OpenID Connect: https://openid.net/specs/openid-connect-frontchannel-1_0.html#ThirdPartyContent; basically, many browsers block the cookie value from other websites.

    You can check the microsoft documentation too: https://learn.microsoft.com/en-us/entra/identity-platform/reference-third-party-cookies-spas

    To solve it, you need to use a custom domain. In my case, it's something I will need, so it becomes a bit convenient. My Azure AD B2C is using a new subdomain called login.mydomain.com, and my apps are at app1.mydomain.com and app2.mydomain.com. So when the iframe calls app1.mydomain.com/logout, the session is revoked as well, and every logged user/cache is cleared.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.