microsoft-authentication-library-for-dotnet: [Bug] GetAccountAsync not finding Guest account?

Which version of MSAL.NET are you using? MSAL.NET 4.35.0

Platform Asp.Net Core 3.1

What authentication flow has the issue?

  • Desktop / Mobile
    • Interactive
    • Integrated Windows Authentication
    • Username Password
    • Device code flow (browserless)
  • Web app
    • Authorization code
    • On-Behalf-Of
  • Daemon app
    • Service to Service calls

Is this a new or existing app? a. The app is in production, and I have upgraded to a new version of MSAL.

Expected behavior ConfidentialClientApplication.GetAccountAsync not finding a guest account which has been added to the cache.

Actual behavior I’m seeing some funnies with MSAL.Net (4.35 and 4.29) with regards to Guest accounts. I tried on 4.29 with no success so upgraded to 4.35 and have encountered the same problem.

Let me preface this by saying I could be making a mistake here also.

I have an asp.net core 3.1 multi-tenant web app configured to use OIDC with AAD as the IDP.

When I am logging into the app as a Guest in the context of the guest tenant I am hitting the https://login.microsoftonline.com/{guest-tenant-id}/oauth2/v2.0/authorize endpoint with response_type=code id_token.

The OpenIdConnect events execute as normal, I get the authorization code and call the AcquireTokenByAuthorizationCode flow which in turn adds it to the token cache. The cache key I am using here is a combination of the oid and tid from the first tenant profile.

	TenantProfile tenantProfile = args.Account?.GetTenantProfiles().FirstOrDefault();
	string accountId = ClaimsPrincipalExtensions.CreateMsalAccountId( tenantProfile.Oid, tenantProfile.TenantId );

The reason being that my HttpContext.User’s claims only include the oid and tid of the guest user/tenant.

The cache is updated and later when I want to aquire an access token to call the graph api I call the ConfidentialClientApplication.GetAccountAsync using the account identifier of the HttpContext.User and no accounts are found.

I have treble checked the token cache keys and it is the same key value that is being used in the AuthorizationCode flow and the GetAccountAsync/AcquireTokenSilent flow.

The GetAccountAsync logs the following:

[Cache Session Manager] Released cache semaphore
GetAccounts found 1 RTs and 1 accounts in MSAL cache. 
[Region discovery] WithAzureRegion not configured. 
[Region discovery] Azure region was not configured or could not be discovered. Not using a regional authority.
[Instance Discovery] Tried to use network cache provider for login.microsoftonline.com. Success? True. 
GetAccounts found 1 RTs and 1 accounts in MSAL cache after environment filtering. 
[Region discovery] WithAzureRegion not configured. 
[Region discovery] Azure region was not configured or could not be discovered. Not using a regional authority.
[Instance Discovery] Tried to use network cache provider for login.microsoftonline.com. Success? True. 
**Filtered by home account id**. Remaining accounts 0 
Found 0 cache accounts and 0 broker accounts
Returning 0 accounts

The “filtered by home account id” made me do a bit of looking and I see the GetAccountAsync is filtering on the home account values

public async Task<IAccount> GetAccountAsync(string **accountId**, CancellationToken cancellationToken = default)
{
    var accounts = await GetAccountsInternalAsync(ApiIds.GetAccountById, **accountId**, cancellationToken).ConfigureAwait(false);
    return accounts.SingleOrDefault();
}

But the accountid I am searching for is of a guest account and the home account id will be different!

Am I right in thinking this is the source of the problem and I will have to use GetAccountsAsync and filter myself?

Thanks, Donal

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 19 (5 by maintainers)

Most upvoted comments

@jennyf19 @bgavrilMS Just an update on this - I have implemented MIW and for the most part it was fairly straightforward.

I had to take care of the consent myself - mainly because of the way our client and backend talk.

In the signout I had to inject some code in the RedirectToIdentityProviderForSignOut to target the correct tenant signout endpoint - not organizations.

Another thing I noticed in the OIDC signout is - if I am signed into the app against my home tenant and also signed in in a different browser as a Guest in a different tenant - and then sign out of one of the apps - the tokens for all get cleared from the token cache… (because it is using Home Account Id in key. Not sure if there is anything that can be done about this.

One other piece of feedback - AddMicrosoftIdentityWebApi can be a bit confusing as regards the 2 sets of options it takes, the duplication between them and what should be set where. Then EnableTokenAcquisitionToCallDownstreamApi also has options with some further duplication. The merge options code does give decent errors though!