Azure AD B2C session management with MSAL and React.js - Part 2.
Tags: azureadb2c, oauth, identity, react
Published: 2023-02-16 18:33:00

---
title: Azure AD B2C session management with MSAL and React.js - Part 2.
published: true
date: 2023-02-01 00:00:00 UTC
tags: AzureADB2C,OAuth,Identity, React
canonical_url: https://melmanm.github.io/misc/2023/02/01/article5-azure-ad-b2c-session-management-with-MSAL-and-react-js-part2.html
---

This article continues the series, related with session management solutions in Azure AD B2C. [Previous post](https://melmanm.github.io/misc/2023/01/31/article4-azure-ad-b2c-session-management-with-MSAL-and-react-js-part1.html) outlined polling-based approach to determine session status in SSO scope. Today I will focus on **front-channel logout**.

As the article goal is to inspect session management from application perspective, I will refer to the code samples. Code samples originate from to React.js SPA application, supported by MSAL.js library.

* * *

_Full application code is available on my [GitHub](https://github.com/melmanm/react-js-azure-b2c-session-management-sample)._

* * *

## Table of contents

- [Front-channel logout](#front-channel-logout)
- [Configuration of Azure AD B2C](#configuration-of-azure-ad-b2c)
- [MSAL and React.js configuration](#msal-and-reactjs-configuration)
- [Third party LocalStorage access](#third-party-localstorage-access)

## Front-channel logout

Front-channel logout idea is based on user logout notification, broadcasted by Azure AD B2C to all applications sharing the same user session. Usually, in response to the notification, application drops current user context and redirect user to login page (to indicate reauthentication is required).

Front-channel logout procedure starts after one application in SSO scope initiates [OpenId Connect logout procedure](https://openid.net/specs/openid-connect-rpinitiated-1_0.html), by sending a request to Azure AD B2C _/logout_ endpoint.

```
GET <tenantname.b2clogin.co/<tenantname>.onmicrosoft.com/<policy_name>/oauth2/v2.0/logout 
?post_logout_redirect_uri=<redirect uri, application will be redirected to this uri after logout once finishes> 
&id_token_hint=<id_token_hint> 

```

Below diagram shows the procedure of front-channel logout in SSO environment.

![front channel logout](https://melmanm.github.io/assets/img/article5/azure-b2c-front-channel-logout.png)

After _/logout_ request, Azure AD B2C recognizes all applications, which use the same session as one passed as a cookie within the request. Next, it creates a list of their front-channel logout URLs.

In response to _/logout_ request, B2C returns a page, which loads an iframe. Iframe includes JavaScript logic calling all URLs listed by Azure AD B2C.

Finally, user is redirected to _post\_logout\_redirect\_uri_ specified in the original request.

## Configuration of Azure AD B2C

To enable front-channel logout in Azure AD B2C, following steps needs to be done

1. **Front-channel logout URL** has to be configured for applications registrations. Given application URL will be called by Azure AD B2C, when any other application in SSO domain initializes logout for the user, who utilizes the same session. Setting is available under _App registration->authentication_. URL needs to be HTTPS for security reasons. Additionally, URL cannot contain fragment component (like example.com#logout). ![front-channel URL](https://melmanm.github.io/assets/img/article5/azure-b2c-front-channel-logout-configuration.jpg)

2. **Custom Policy Configuration**

    `Note that front-channel logout is supported with Custom Policies only.`

    Custom policy *UserJourney* needs to be decorated with *UserJourneyBehaviors*.
    *  Scope of *SingleSignOn* can be set to **Tenant**, **Application** or **Policy**. 
    * *EnforceIdTokenHint* option is required, so the current user context is always passed within /logout request to Azure AD B2C. Note that front-channel logout is supported only with Custom Policies. 

    ```xml
    <UserJourneyBehaviors> 
        <SingleSignOn Scope="Tenant" EnforceIdTokenHintOnLogout="true"/> 
    </UserJourneyBehaviors> 
    ```


## MSAL and React.js configuration

React.js & MASL application requires following configuration

1. **MSAL configuration** – MSAL configuration is expressed in JSON format. It is used to instantiate MASL application instance. 
    * *allowRedirectInIframe: true* – application needs to be reached from iframe, rendered in Azure AD B2C tenant domain. This property ensures *X-Frame-Options: DENY* is not added in http header. 
    * *cacheLocation: "localStorage"* - MSAL stores user related information in browser storage. 

    ```javascript
    const msalInstance = new PublicClientApplication({  
    auth: {  
         //auth config  
    }, cache: {  
         cacheLocation: "localStorage",   
    }, system: {  
         allowRedirectInIframe: true  
    }})
    ```

2. **Logout endpoint** – application needs to provide a logout endpoint, at the URL corresponding with Azure AD B2C registration. React.js framework is not natively prepared for handleing routing, however uisng React-router, it is possible to serve specific content on _/logout_ endpoint. Using _BrowserRouter_ component, _/logout_ request can be routed to specific application component. 

    ```xml
    <BrowserRouter>
        <Routes>
            <Route path="/logout" element={<Logout />} />
            <Route path="/" element={<Home />} />
        </Routes>
    </BrowserRouter>
    ```
    Logout component should not contain much logic. It needs to perform well. Note that once user logs out from other application in SSO domain, component is loaded using front-channel request. The longer it takes to load, the longer user waits for Azure AD B2C to complete original logout request. Logout component can be designed as follows:
    ```jsx
    import { React } from "react"; 
    import { useMsal } from "@azure/msal-react"; 
    
    export function Logout() { 
        const { instance } = useMsal(); 
    
        instance.logoutRedirect({ 
            account: instance.getActiveAccount(), 
            onRedirectNavigate: false 
        }); 
    
        return ( 
            <div>Logout</div> 
        ) 
    }    
    ```
    Setting *onRedirectNavigate: false* ensures that only local logout will be performed. Once onRedirectNavigate is set to true, local logout is followed by calling */logout* endpoint of Azure AD B2C.


3. **Handle account storage events** – MSAL stores its internal status, including current user related data, in browser storage (localStorage – according to configured). Since the same application can be opened in many browser tabs/windows, MSAL has to react on changes in localStorage entries. In result all tabs/windows with the same application opened, can synchronize current user context. To enable this mechanism, following function needs to be executed on PublicClientApplication. 

    ```js
    msalInstance.enableAccountStorageEvents(); 
    ```
    **Handling storage events is also critical in the context of front-channel logout**. After application’s */logout* endpoint is called by Azure AD B2C iframe, user context is removed from localStorage. If application is opened in different browser tab or window, it can to be notified about this change.

## Third party LocalStorage access

Application logout endpoint, loaded from Azure AD B2C iframe, needs to access localStorage. Unless Azure AD B2C is configured using [Azure Front Door](https://learn.microsoft.com/en-us/azure/active-directory-b2c/custom-domain?pivots=b2c-custom-policy), to be available from the same domain as application, it can lead to some difficulties.

Some browsers, controls localStorage access using the third-party cookies settings. Once it is disabled, localStorage cannot be accessed from website iframed in a different domain. Since more and more browsers restricts cross domain access to storage, it needs to be considered. ![3rd party cookie](https://melmanm.github.io/assets/img/article5/google-cookies.jpg)