AzureAD / microsoft-authentication-library-for-java

Microsoft Authentication Library (MSAL) for Java http://aka.ms/aadv2
MIT License
280 stars 137 forks source link

[Bug] WAM Broker is Failing on x86 (jdk 17) #789

Open rijami00 opened 4 months ago

rijami00 commented 4 months ago

Library version used

1.14.2

Java version

openjdk 17.0.10 2024-01-16 OpenJDK Runtime Environment Temurin-17.0.10+7 (build 17.0.10+7) OpenJDK Client VM Temurin-17.0.10+7 (build 17.0.10+7, mixed mode, emulated-client)

Windows version

Edition Windows 11 Pro Version 23H2 OS build 22631.3155 Experience Windows Feature Experience Pack 1000.22684.1000.0 System type 64-bit operating system, x64-based processor

Scenario

PublicClient (AcquireTokenInteractive, AcquireTokenByUsernamePassword)

Is this a new or an existing app?

This is a new app or experiment

Issue description and reproduction steps

Hi. First of all, thank you for this wonderful library.

We are trying to implement a login for a sofftware where we have to use x86 (32 bits) version of JDK (17).

The PoC works fine when tested on JDK 17 (or 21) x64 but it falls flat when x86 version is used.

I have tried to debug this and found some stuff that can be used to further debug this. I am not sure if I can progress further as this package seems to be missing (or no permission): https://github.com/AzureAD/microsoft-authentication-library-for-cpp

Interestingly, if we avoid the WAM broker, it opens the browser and seems to work.

We have an invalid memory access and an error about not being able to set redirect URI (because it is '') but when we provide this, it is not empty.

Error Logs when using acquireTokenSilently:

[main] INFO com.microsoft.azure.javamsalruntime.MsalRuntimeInterop - Setting up MSALRuntime.
[main] INFO com.microsoft.azure.javamsalruntime.Callbacks - (MSALRuntime log) [MSAL:0001]   INFO    Startup:53  Starting up MSAL
[main] INFO com.microsoft.azure.javamsalruntime.Callbacks - (MSALRuntime log) [MSAL:0001]   INFO    AddConfigurationWithStorageManager:195  Created a new public client application with ID ''
[main] INFO com.microsoft.azure.javamsalruntime.MsalRuntimeInterop - MSALRuntime startup API called successfully.
[main] INFO com.microsoft.aad.msal4jbrokers.Broker - MSALRuntime started successfully. MSAL Java will use MSALRuntime in all supported broker flows.

Exception in thread "main" java.lang.Error: Invalid memory access
    at com.sun.jna.Native.invokePointer(Native Method)
    at com.sun.jna.Function.invokePointer(Function.java:497)
    at com.sun.jna.Function.invoke(Function.java:441)
    at com.sun.jna.Function.invoke(Function.java:361)
    at com.sun.jna.Library$Handler.invoke(Library.java:265)
    at jdk.proxy1/jdk.proxy1.$Proxy1.MSALRUNTIME_SignInSilentlyAsync(Unknown Source)
    at com.microsoft.azure.javamsalruntime.MsalRuntimeInterop.signInSilently(MsalRuntimeInterop.java:148)
    at com.microsoft.aad.msal4jbrokers.Broker.acquireToken(Broker.java:69)
    at com.microsoft.aad.msal4j.PublicClientApplication.acquireTokenSilently(PublicClientApplication.java:143)
    at WebAccountManager.main(WebAccountManager.java:51)
[Thread-0] INFO com.microsoft.azure.javamsalruntime.MsalRuntimeInterop - Shutting down MSALRuntime.
[Thread-0] INFO com.microsoft.azure.javamsalruntime.MsalRuntimeInterop - MSALRuntime shutdown API called successfully.

Error logs when using InteractiveRequestParameters :

[main] INFO com.microsoft.azure.javamsalruntime.MsalRuntimeInterop - Setting up MSALRuntime.
[main] INFO com.microsoft.azure.javamsalruntime.Callbacks - (MSALRuntime log) [MSAL:0001]   INFO    Startup:53  Starting up MSAL
[main] INFO com.microsoft.azure.javamsalruntime.Callbacks - (MSALRuntime log) [MSAL:0001]   INFO    AddConfigurationWithStorageManager:195  Created a new public client application with ID ''
[main] INFO com.microsoft.azure.javamsalruntime.MsalRuntimeInterop - MSALRuntime startup API called successfully.
[main] INFO com.microsoft.aad.msal4jbrokers.Broker - MSALRuntime started successfully. MSAL Java will use MSALRuntime in all supported broker flows.

[main] WARN com.microsoft.azure.javamsalruntime.Callbacks - (MSALRuntime log) [MSAL:0001]   WARNING SetRedirectUri:89   Not setting redirect URI '' because it couldn't be parsed.
[main] ERROR com.microsoft.azure.javamsalruntime.Callbacks - (MSALRuntime log) [MSAL:0001]  ERROR   ErrorInternalImpl:134   Created an error: 6o2hl, StatusInternal::ApiContractViolation, InternalEvent::None, Error Code 0, Context 'Invalid handle'
[main] WARN com.microsoft.azure.javamsalruntime.Error - MSALRuntime returned a non-zero MSALRUNTIME_ERROR_HANDLE.
[main] INFO com.microsoft.azure.javamsalruntime.Error - Parsing MSALRuntime error response.
[main] ERROR com.microsoft.azure.javamsalruntime.Callbacks - (MSALRuntime log) [MSAL:0001]  ERROR   ErrorInternalImpl:134   Created an error: 6o2hl, StatusInternal::ApiContractViolation, InternalEvent::None, Error Code 0, Context 'Invalid handle'
[main] ERROR com.microsoft.azure.javamsalruntime.Callbacks - (MSALRuntime log) [MSAL:0001]  ERROR   ErrorInternalImpl:134   Created an error: 6o2hl, StatusInternal::ApiContractViolation, InternalEvent::None, Error Code 0, Context 'Invalid handle'
[main] ERROR com.microsoft.azure.javamsalruntime.Callbacks - (MSALRuntime log) [MSAL:0001]  ERROR   ErrorInternalImpl:134   Created an error: 6o2hl, StatusInternal::ApiContractViolation, InternalEvent::None, Error Code 0, Context 'Invalid handle'
[main] ERROR com.microsoft.azure.javamsalruntime.Callbacks - (MSALRuntime log) [MSAL:0001]  ERROR   ErrorInternalImpl:134   Created an error: 6o2hl, StatusInternal::ApiContractViolation, InternalEvent::None, Error Code 0, Context 'Invalid handle'
[main] WARN com.microsoft.azure.javamsalruntime.ErrorHelper - Unexpected response status from MSALRuntime. Expected: 10 | Actual: 6
[main] WARN com.microsoft.azure.javamsalruntime.HandleBase - Could not parse string.
Exception in thread "main" com.microsoft.aad.msal4j.MsalClientException: MSALRuntime exception: Context:  | Response status: MSALRUNTIME_RESPONSE_STATUS_UNEXPECTED | Tag: 0 | Error code: 0
    at com.microsoft.aad.msal4jbrokers.Broker.acquireToken(Broker.java:126)
    at com.microsoft.aad.msal4j.PublicClientApplication.acquireToken(PublicClientApplication.java:128)
    at WebAccountManager.main(WebAccountManager.java:68)
[Thread-0] INFO com.microsoft.azure.javamsalruntime.MsalRuntimeInterop - Shutting down MSALRuntime.
[Thread-0] INFO com.microsoft.azure.javamsalruntime.MsalRuntimeInterop - MSALRuntime shutdown API called successfully.

Relevant code snippets

public class WebAccountManager {
    public static final String APPLICATION_NAME = "Desktop";
    public static final URI REDIRECT_URI = URI.create("http://localhost");;

    private static String clientId;
    private static String tenantId;
    private static Set<String> scope;
    private static String authority;

    public static void main(String[] args) throws IOException {
        readConfig(); // reads from somewhere

        long consoleHandleValue = 58527858L;    // hardcoded for now

        Broker wamBroker = new Broker.Builder().supportWindows(true).build();   // the WAM broker
        wamBroker.enableBrokerLogging(true);
        wamBroker.enableBrokerPIILogging(true);
        PublicClientApplication pca = PublicClientApplication.builder(clientId)
                                                             .broker(wamBroker)     // set the broker
                                                             .authority(authority)
                                                             .applicationName(APPLICATION_NAME)
                                                             .build();

//        pca.acquireTokenSilently(SilentParameters.builder(scope).build()).exceptionally(ex -> {
//            System.out.println("Unable to acquire token silently");
//            return null;
//        }).thenAccept(result -> {
//            if (result != null) {
//                inspectResult(result);
//            }
//        }).join();

        var interactiveRequestParams = InteractiveRequestParameters.builder(REDIRECT_URI)
                                                                   .scopes(scope)
                                                                   .windowHandle(consoleHandleValue)
                                                                   .instanceAware(true)
                                                                   .tenant(tenantId)
                                                                   .build();

        pca.acquireToken(interactiveRequestParams).exceptionally(ex -> {
            ex.printStackTrace();

            return null;
        }).thenAcceptAsync(result -> {
            if (result != null) {
                inspectResult(result);
            }
        }).join();

        inspectApplication(pca);
    }

    private static void readConfig() throws IOException {
        Properties properties = new Properties();
        properties.load(new FileInputStream(Objects.requireNonNull(Thread.currentThread()
                                                                         .getContextClassLoader()
                                                                         .getResource(""))
                                                   .getPath() + "application.properties"));
        clientId = properties.getProperty("CLIENT_ID");
        tenantId = properties.getProperty("TENANT_ID");
        scope = Collections.singleton(properties.getProperty("SCOPE"));
        authority = properties.getProperty("AUTHORITY");
    }

    private static void inspectApplication(PublicClientApplication pca) {
        System.out.println("Name:                " + pca.applicationName());
        System.out.println("Version:             " + pca.applicationVersion());
        System.out.println("Client ID:           " + pca.clientId());
        System.out.println("Capabilities:        " + pca.clientCapabilities());
        System.out.println("Authority:           " + pca.authority());
        System.out.println("Azure Region:        " + pca.azureRegion());
        System.out.println("Correlation ID:      " + pca.correlationId());
        System.out.println("Validate Authority:  " + pca.validateAuthority());
        System.out.println("Token cache:         " + pca.tokenCache().toString());

        System.out.println("Accounts in cache:");
        pca.getAccounts().join().forEach(account -> {
            System.out.println("- Username: " + account.username());
        });
    }

    private static void inspectResult(IAuthenticationResult result) {
        System.out.println("Account username: " + result.account().username());
        System.out.println("Access token:     " + result.accessToken());
        System.out.println("Id token:         " + result.idToken());
        System.out.println("Home account id:  " + result.account().homeAccountId());
        System.out.println("Environment:      " + result.account().environment());
        System.out.println("Scopes:           " + result.scopes());
        System.out.println("Expires on:       " + result.expiresOnDate());
        System.out.println("Tenant id:        " + result.tenantProfile().toString());
    }
}

Pom file:

        <!-- https://mvnrepository.com/artifact/com.microsoft.azure/msal4j -->
        <dependency>
            <groupId>com.microsoft.azure</groupId>
            <artifactId>msal4j</artifactId>
            <version>1.14.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.microsoft.azure/msal4j-brokers -->
        <dependency>
            <groupId>com.microsoft.azure</groupId>
            <artifactId>msal4j-brokers</artifactId>
            <version>1.0.0</version>
        </dependency>


### Expected behavior

Works without any invalid memory access issues and gets the token.

### Identity provider

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

### Regression

_No response_

### Solution and workarounds

None so far.
rijami00 commented 4 months ago

Another thing to note is that sometimes, I get this error right after redirect URI fail error line but it is not consistent.

[main] WARN com.microsoft.azure.javamsalruntime.Callbacks - (MSALRuntime log) [MSAL:0001]   WARNING WcharToUtf8:27  Failed to convert UTF16 into UTF8: 0x00000459
bgavrilMS commented 4 months ago

@ashok672 - I think you fixed a bunch of memory issues in msal runtime. Is there a java package that can be updated?

rijami00 commented 4 months ago

Hi.

I'm wondering if WAM broker working on 32bit java is part of supported scope?

I can confirm that if I don't use the WAM broker, it works perfectly even in 32bit java.

crimsonvspurple commented 2 months ago

Bump. Any update on this?