Secure Single Sign Out in Azure AD B2C

Introduction:

Single sign-out is a crucial feature for applications focused on security and delivering a seamless user experience. With Azure AD B2C, enabling single sign-out ensures that when users log out of one application, they are automatically signed out of all active sessions across other connected applications. This article offers a step-by-step guide to configuring this functionality.

Single Sign-Out Flow

  • Step 1: The user clicks the “Logout” button in the application.
  • Step 2: The user is redirected to the end_session_endpoint URL so Azure AD B2C can invalidate the cookie-based session
  • Step 3: Azure AD B2C simultaneously sends an HTTP GET request to the registered logout URL of all the applications that the user is currently signed in to.
  • Step 4: When all the applications have been notified of the log-out, the user is redirected to the requested post_logout_redirect_uri including the optional state parameter specified in the initial request.

Make sure the post_logout_redirect_uri is configured as one of the redirect URIs in Azure AD B2C app registration

  • The application deletes all the cookies and tokens.

This is a normal logout process. To implement secure single-sign-out, the application should pass the id_token_hint along with the logout request to the Azure AD B2C.

Enable Secure Sign-Out

Secure sign-out can be enabled through normal user flow and custom policy

To allow secure sign-out from user flow, select the user flow from the Azure portal and set yes to Require ID Token in Logout requests under the Session behavior section

For Custom Policy set EnforceIdTokenHintOnLogout attribute to true for a User Journey Behavior in the rely parties.

<UserJourneyBehaviors> <SingleSignOn Scope="Tenant" EnforceIdTokenHintOnLogout="true"/> </UserJourneyBehaviors>
  • Required ID Token in logout request can be enabled
  • It means that during the logout, the application must pass the id_token_hint parameter
Why Id_token_hint required?

When Azure AD B2C attempts to sign out from federated identity providers, it will not pass the ID_token_hint parameter by default.  

If the federated identity provider requires id_token_hint parameter, the sign-out request will fail.

It is possible to disable sign-out from federated identity providers. This is the most recommended approach for the secure single sign out.

  • This parameter is the ID Token that contains information about the currently authenticated user
   [HttpGet("{scheme?}")]
   public async Task<IActionResult> SignOutAsync([FromRoute] string scheme)
   {
       // Set the default authentication scheme if none is provided
       scheme ??= OpenIdConnectDefaults.AuthenticationScheme;

       // Authenticate the user using the provided scheme
       var authenticateResult = await HttpContext.AuthenticateAsync(scheme);

       // Retrieve the ID token from the authentication result
       var idToken = authenticateResult.Properties.GetTokenValue("id_token");

       // Define the callback URL to redirect to after sign-out
       var callbackUrl = Url.Content("https://localhost:44373/");

       // Create authentication properties with the callback URL
       var properties = new AuthenticationProperties { RedirectUri = callbackUrl };

       // Add the ID token hint to the properties
       properties.Items.Add("id_token_hint", idToken);

       // Sign the user out using the specified schemes
       return SignOut(properties, CookieAuthenticationDefaults.AuthenticationScheme, scheme);
   }

This C# action method handles the sign-out process for the user and add the id_token_hint for the logout request send to Azure AD B2C.

    configureMicrosoftIdentityOptions.Events.OnRedirectToIdentityProviderForSignOut = async context =>
    {
        var id_token_hint = context.Properties.Items.FirstOrDefault(x => x.Key == "id_token_hint").Value;
        if (id_token_hint != null)
        {
            context.ProtocolMessage.SetParameter("id_token_hint", id_token_hint);
            context.ProtocolMessage.PostLogoutRedirectUri = context.Request.Scheme + "://" + context.Request.Host;
        }
          
        await Task.CompletedTask.ConfigureAwait(false);
    };

The above event OnRedirectToIdentityProviderForSignOut will add the id_token_hint to the log out request that send to Azure AD B2C.

  • Azure AD B2C verifies that the value of post_logout_redirect_uri matches one of the application’s configured redirects URIs before performing the redirect
  • When Azure AD B2C receives the logout request, it uses a front-channel HTML iframe to send an HTTP GET request to the registered logout URL of each participating application that the user is currently signed in to. This URL is configured in the front-channel logout URL field on application registration.
[HttpGet("{scheme?}")]
    public async Task<IActionResult> RemoteSignOut([FromRoute] string scheme)
    {
        // Set the default authentication scheme if none is provided
        scheme ??= OpenIdConnectDefaults.AuthenticationScheme;

        // Define the redirect URL to redirect to after sign-out
        var redirectUrl = Url.Content("~/");

        // Create authentication properties with the redirect URL
        var properties = new AuthenticationProperties { RedirectUri = redirectUrl };

        // Sign the user out using the specified schemes
        return SignOut(properties, CookieAuthenticationDefaults.AuthenticationScheme, scheme);
    }

The above action executes when the Azure AD B2C triggers.

Make sure you configure the post log out url in the Redirect URI section

Weather App configuration

To-Do App Configuration

Configure Cookie Same Site Setting

     To clear the cookies on the application side when Azure AD B2C sends an HTTP Get request, we must set the application cookie to SameSite=none and add the Secure attribute. We cannot use SameSite = Lax since Azure AD B2C uses a hidden iframe to make the HTTP Get request.

If the same domain is used for the application’s registration, like apps.abc.com or dev.abc.com, configuring the front channel logout URL and changing the cookie samesite property from lax to none is not required since both applications use the same domain cookie.

    configureCookieAuthenticationOptions: options =>
        {
            options.Cookie.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None;
            options.Cookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.Always;            
         
        },
        OpenIdConnectDefaults.AuthenticationScheme,
        CookieAuthenticationDefaults.AuthenticationScheme);

login to SSO apps to test the secure single out, In my case I logged in to two apps https://gowthamb2capp.azurewebsites.net/ and another is from local host https://localhost:44373/

When I do Sign out from https://gowthamb2capp.azurewebsites.net/ , it create a GET request to https://localhost:44373/CustomAccount/RemoteSignOut(configured as a front door url for weather app) action through the hidden iframe, please check below screenshot for the request trace.

Summary:

This article explores the importance of secure single sign-out in Azure AD B2C applications, emphasizing its role in enhancing security and improving user experience. It provides a detailed, step-by-step guide to implementing single sign-out, ensuring users are automatically logged out of all active sessions across multiple applications after signing out from one. The article also highlights best practices for secure session management and offers insights.

Useful Links:

https://github.com/gowthamece/Azure_B2C_Samples/tree/main

https://learn.microsoft.com/en-us/azure/active-directory-b2c/session-behavior?pivots=b2c-custom-policy#sign-out

Gowtham K

Gowtham K has been awarded as MVP(Most Valuable Professional) for 9 times by Microsoft for his exceptional contribution in Microsoft technologies under the category “Developer Technologies & Security” . He has more than 12 years of experience on Microsoft technologies such as C#, ASP.NET MVC, ASP.NET WEB API, ASP.NET Core, MS SQL Server, Azure, Microsoft Entra ID, Azure AD B2C and other technologies such as JavaScript, jQuery, HTML and CSS .He is also a blogger and author of articles on various technologies. He is also a speaker and delivered talk on various technologies like ASP.NET MVC, Azure and Azure DevOps in the public events.

Leave a Reply

Your email address will not be published. Required fields are marked *