Skip to content

[Bug] IAuthenticationResult.tenantProfile() always returns null #1076

Open

Description

Library version used

1.26.0

Java version

11.0.13

Scenario

ConfidentialClient - web site (AcquireTokenByAuthCode)

Is this a new or an existing app?

The app is in production, and I have upgraded to a new version of MSAL

Issue description and reproduction steps

After upgrading from 1.18.0 to 1.26.0 I got a NPE in our application when attempting to log in and get the claims from the ITenantProfile. It seems to me that this is due to a bug. In the class com.microsoft.aad.msal4j.AuthenticationResult, the method public ITenantProfile tenantProfile() always returns null, because the field tenantProfile is always null. This field is assigned in the declaration by result of getTenantProfile(), but this method always returns null because idToken is not yet initialized.

Relevant code snippets

package com.microsoft.aad.msal4j;

import org.junit.Test;

public class MsalTest {
    @Test
    public void test() {
        System.out.println("java version: " + System.getProperty("java.version"));
        final String idToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
        final AccountCacheEntity accountCacheEntity = new AccountCacheEntity() {};
        final AuthenticationResult result = new AuthenticationResult("accessToken", 123456, 123456, "refreshToken", 123456L, "familyId", idToken, accountCacheEntity, "environment", "scopes", null, true);
        System.out.println("tenantProfile: " + result.tenantProfile());
    }

}

Expected behavior

The result of the code is:

java version: 11.0.13
tenantProfile: null

The expected behavior is (and in fact was in 1.18.0):

java version: 11.0.13
tenantProfile: com.microsoft.aad.msal4j.TenantProfile@f2ff811

Identity provider

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

Regression

1.18.0

Solution and workarounds

The work-around for getting the claims is parsing them yourself from the idToken instead of getting them from the tenantProfile().

Activity

  1. added
    needs attentionAutomatically used when an issue is created through an issue template
    untriagedAutomatically used when an issue is created through an issue template
    on Oct 14, 2026
  2. basitalisandhu commented on Oct 20, 2026

    @basitalisandhu

    Confirmed on dev (30dbbed), and your reading is right. It started in 1.23.0: up to 1.22.0 these were Lombok @Getter(lazy = true) fields, and the Lombok removal (67d3131) kept the initializers without the lazy getter, so they now run before the constructor assigns idToken. The package-private idTokenObject() has the same problem. account() is fine because it is computed on each call.

    I opened #1078: both values are derived on access again, with tests that fail on dev and pass with the change.

    Until a release has it, reading the claims from the ID token yourself works on 1.23.0+. Note that result.account().getTenantProfiles() does not help here, since the account built for the result has no tenant profiles.

    String[] parts = result.idToken().split("\\.");
    String payload = new String(Base64.getUrlDecoder().decode(parts[1]), StandardCharsets.UTF_8);
    // parse payload with your JSON library, e.g. Jackson: new ObjectMapper().readValue(payload, Map.class)

    This is the same plain decode tenantProfile() did (JsonHelper.getTokenPayloadClaims); it does not check the signature, so use it only for tokens you just got from MSAL.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs attentionAutomatically used when an issue is created through an issue templateuntriagedAutomatically used when an issue is created through an issue template

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions