Skip to content

[Bug] AcquireTokenInteractive with system browser hangs indefinitely if the browser is closed before authentication completes. #5552

@gkms225

Description

@gkms225

Library version used

4.76.0

.NET version

.NET Framework 4.7.2

Scenario

PublicClient - desktop app

Is this a new or an existing app?

The app is in production, I haven't upgraded MSAL, but started seeing this issue

Issue description and reproduction steps

When using AcquireTokenInteractive with the system browser, if the user closes the browser window or tab before completing authentication, the ExecuteAsync() task hangs indefinitely. It never throws an exception or returns. Investigation shows the call stack is blocked inside Microsoft.Identity.Client.Platforms.Shared.DefaultOSBrowser.HttpListenerInterceptor.ListenToSingleRequestAndRespondAsync.

Relevant code snippets

Sample:

public class MsalBrowserHangRepro
{
    private const string ClientId = "<public client id>"; // add guid
    private const string TenantId = "common";
    private static readonly string[] Scopes = new[] { "https://database.windows.net/.default" };

    public static void Main(string[] args)
    {
        var t = new Thread(() =>
        {
            try
            {
                Console.WriteLine("Attempting to acquire token. Please close the browser window when it opens.");
                var result = AcquireTokenInteractiveAsync().GetAwaiter().GetResult();
                Console.WriteLine("Success! This should not happen if the browser was closed.");
                Console.WriteLine($"Token acquired for: {result.Account.Username}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Success! The operation failed as expected with exception: {ex.GetType().Name}");
                Console.WriteLine(ex.Message);
            }
        });

        t.SetApartmentState(ApartmentState.STA);
        t.Start();
        t.Join();

        Console.WriteLine("Press any key to exit...");
        Console.ReadKey();
    }

    private static async Task<AuthenticationResult> AcquireTokenInteractiveAsync()
    {
        var pca = PublicClientApplicationBuilder
            .Create(ClientId)
            .WithAuthority(AzureCloudInstance.AzurePublic, TenantId)
            .WithRedirectUri("http://localhost")
            .WithLogging((level, message, containsPii) =>
            {
                Console.WriteLine($"MSAL {level}: {message}");
            }, LogLevel.Verbose, enablePiiLogging: true)
            .Build();

        Console.WriteLine("Calling AcquireTokenInteractive... The application will now hang if you close the browser.");

        // This task will hang indefinitely if the browser is closed before authentication
        var authResultTask = pca.AcquireTokenInteractive(Scopes)
            .WithUseEmbeddedWebView(false)
            .ExecuteAsync();

        return await authResultTask;
    }
}

Expected behavior

When the user closes the browser window during an interactive sign-in, the ExecuteAsync() task throws an MsalClientException or something similar to indicate the user flow has been aborted.

Identity provider

Microsoft Entra ID (Work and School accounts and Personal Microsoft accounts)

Regression

No response

Solution and workarounds

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions