Skip to content

[Bug] Error when acquiring token silently #869

@q-benwillis

Description

@q-benwillis

Library version used

1.15.1

Java version

openjdk version "17.0.11" 2024-04-16 LTS

Scenario

ConfidentialClient - web api (AcquireTokenOnBehalfOf)

Is this a new or an existing app?

This is a new app or experiment

Issue description and reproduction steps

Seeing the following NPE when attempting to acquire a token silently:

2024-10-08T11:43:08.732+01:00 DEBUG 33188 --- [app] [onPool-worker-2] c.m.aad.msal4j.TokenRequestExecutor      : Sending token request to: https://login.microsoftonline.com/<tenant-id>/
2024-10-08T11:43:08.939+01:00 DEBUG 33188 --- [app] [onPool-worker-2] c.m.a.m.ConfidentialClientApplication    : [Correlation ID: 98cfdbb2-3240-425c-a7c2-6622960f493b] Access Token and Refresh Token were returned
2024-10-08T11:43:11.024+01:00  WARN 33188 --- [app] [onPool-worker-2] c.m.a.m.ConfidentialClientApplication    : [Correlation ID: 779911f4-83a1-4940-97fe-2b676dc6c5c1] Execution of class com.microsoft.aad.msal4j.AcquireTokenSilentSupplier failed: Cannot invoke "String.equals(Object)" because "accessToken.homeAccountId" is null
2024-10-08T11:43:11.024+01:00  WARN 33188 --- [app] [  io-compute-15] c.q.f.s.FabricAuthenticationClientImpl   : Failed to get token silently using session ID, getting OBO token using subject token

java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "accessToken.homeAccountId" is null
        at com.microsoft.aad.msal4j.TokenCache.lambda$getAccessTokenCacheEntity$3(TokenCache.java:481) ~[msal4j-1.15.1.jar:1.15.1]
        at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:178) ~[na:na]
        at java.base/java.util.Spliterators$IteratorSpliterator.tryAdvance(Spliterators.java:1856) ~[na:na]
        at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129) ~[na:na]
        at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527) ~[na:na]
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513) ~[na:na]
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na]
        at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150) ~[na:na]
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
        at java.base/java.util.stream.ReferencePipeline.findAny(ReferencePipeline.java:652) ~[na:na]
        at com.microsoft.aad.msal4j.TokenCache.getAccessTokenCacheEntity(TokenCache.java:487) ~[msal4j-1.15.1.jar:1.15.1]
        at com.microsoft.aad.msal4j.TokenCache.getCachedAuthenticationResult(TokenCache.java:617) ~[msal4j-1.15.1.jar:1.15.1]
        at com.microsoft.aad.msal4j.AcquireTokenSilentSupplier.execute(AcquireTokenSilentSupplier.java:29) ~[msal4j-1.15.1.jar:1.15.1]
        at com.microsoft.aad.msal4j.AuthenticationResultSupplier.get(AuthenticationResultSupplier.java:69) ~[msal4j-1.15.1.jar:1.15.1]
        at com.microsoft.aad.msal4j.AuthenticationResultSupplier.get(AuthenticationResultSupplier.java:18) ~[msal4j-1.15.1.jar:1.15.1]
        at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1768) ~[na:na]
        at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1760) ~[na:na]
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373) ~[na:na]
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182) ~[na:na]
        at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655) ~[na:na]
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622) ~[na:na]
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165) ~[na:na]

I've acquired an Authentication Result using the OnBehalfOfParameters and am now trying to get a token silently using the account from the first Authentication Result.

I've seen this working in some of my test scenarios but in the deployed version of my application I get this warning and null pointer exception.

Relevant code snippets

No response

Expected behavior

Retrieve token silently using account

Identity provider

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

Regression

No response

Solution and workarounds

I feel like here we could just check that homeAccountId isn't null for each access token?

I think it's because I have previously requested an app token which is stored in the same cache, I could also perhaps use two different confidential clients.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugSomething isn't working, needs an investigation and a fixP2Normal priority items, should be done after P1confidential-clientFor issues related to confidential client apps

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions