microsoft-authentication-library-for-java icon indicating copy to clipboard operation
microsoft-authentication-library-for-java copied to clipboard

[Bug] Unable to launch default browser on Windows when running in headless mode

Open humbertogrobles opened this issue 1 month ago • 4 comments

Library version used

1.20.1

Java version

21.0.8

Scenario

PublicClient (AcquireTokenInteractive, AcquireTokenByUsernamePassword)

Is this a new or an existing app?

This is a new app or experiment

Issue description and reproduction steps

I'm working on an extension for VS Code that runs a Java backend server in headless mode. I'm planning on adding support for EntraID, and from what I understand that requires being able to open the default browser to authenticate. Since the backend server is running in headless mode (java.awt.headless=true), the browser fails to be launched on Windows, since the following method relies on java.awt.Desktop which is not available on headless mode:

AcquireTokenByInteractiveFlowSupplier class:

private static void openDefaultSystemBrowserInWindows(URL url){

    try {

        if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {

            Desktop.getDesktop().browse(url.toURI());

            LOG.debug("Opened default system browser");

        } else {

            throw new MsalClientException("Unable to open default system browser",

                    AuthenticationErrorCode.DESKTOP_BROWSER_NOT_SUPPORTED);

        }

    } catch (URISyntaxException | IOException ex) {

        throw new MsalClientException(ex);

    }

}

On the other hand, when running on Mac, that platform's method doesn't rely on AWT, and instead relies on a native command, so launching the browser works without problems even in headless mode:

private static void openDefaultSystemBrowserInMac(URL url){

    Runtime runtime = Runtime.getRuntime();

    try {

        // CodeQL [SM00680] False positive: this URL is validated earlier in the interactive flow

        runtime.exec("open " + url);

    } catch (IOException e) {

        throw new RuntimeException(e);

    }

}

Relevant code snippets

Relevant stacktrace:

Suppressed: com.microsoft.aad.msal4j.MsalClientException: Unable to open default system browser
		at [email protected]/com.microsoft.aad.msal4j.AcquireTokenByInteractiveFlowSupplier.openDefaultSystemBrowserInWindows(AcquireTokenByInteractiveFlowSupplier.java:155)
		at [email protected]/com.microsoft.aad.msal4j.AcquireTokenByInteractiveFlowSupplier.openDefaultSystemBrowser(AcquireTokenByInteractiveFlowSupplier.java:139)
		at [email protected]/com.microsoft.aad.msal4j.AcquireTokenByInteractiveFlowSupplier.getAuthorizationResult(AcquireTokenByInteractiveFlowSupplier.java:70)
		at [email protected]/com.microsoft.aad.msal4j.AcquireTokenByInteractiveFlowSupplier.execute(AcquireTokenByInteractiveFlowSupplier.java:46)
		at [email protected]/com.microsoft.aad.msal4j.AuthenticationResultSupplier.get(AuthenticationResultSupplier.java:69)
		at [email protected]/com.microsoft.aad.msal4j.AuthenticationResultSupplier.get(AuthenticationResultSupplier.java:18)
		at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1768)
		... 6 more

Expected behavior

To be able to launch the browser needed for authentication on Windows with headless mode, just like it can be done on Mac.

Identity provider

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

Regression

No response

Solution and workarounds

A suggestion would be to also use a native method on Windows, like "start".

humbertogrobles avatar Oct 16 '25 15:10 humbertogrobles