AzureAD / microsoft-authentication-library-for-dotnet

Microsoft Authentication Library (MSAL) for .NET
https://aka.ms/msal-net
MIT License
1.37k stars 337 forks source link

[Bug] AcquireTokenInteractive WithAccount fails with user_mismatch if user chooses another account from account chooser #3991

Closed andrensairr closed 1 year ago

andrensairr commented 1 year ago

Logs and network traces

MSAL Info False MSAL 4.50.0.0 MSAL.Desktop 4.8 or later Windows 10 Pro [2023-03-06 23:25:43Z - c5490327-1e27-4d0c-bf7b-ff85618574f7] MSAL MSAL.Desktop with assembly version '4.50.0.0'. CorrelationId(c5490327-1e27-4d0c-bf7b-ff85618574f7)
MSAL Info False MSAL 4.50.0.0 MSAL.Desktop 4.8 or later Windows 10 Pro [2023-03-06 23:25:43Z - c5490327-1e27-4d0c-bf7b-ff85618574f7] === InteractiveParameters Data ===
LoginHint provided: True
User provided: True
UseEmbeddedWebView: NotSpecified
ExtraScopesToConsent: 
Prompt: no_prompt
HasCustomWebUi: False

MSAL Info False MSAL 4.50.0.0 MSAL.Desktop 4.8 or later Windows 10 Pro [2023-03-06 23:25:43Z - c5490327-1e27-4d0c-bf7b-ff85618574f7] 
=== Request Data ===
Authority Provided? - True
Scopes - offline_access https://outlook.office.com/SMTP.Send
Extra Query Params Keys (space separated) - 
ApiId - AcquireTokenInteractive
IsConfidentialClient - False
SendX5C - False
LoginHint ? True
IsBrokerConfigured - False
HomeAccountId - False
CorrelationId - c5490327-1e27-4d0c-bf7b-ff85618574f7
UserAssertion set: False
LongRunningOboCacheKey set: False
Region configured: 

MSAL Info False MSAL 4.50.0.0 MSAL.Desktop 4.8 or later Windows 10 Pro [2023-03-06 23:25:43Z - c5490327-1e27-4d0c-bf7b-ff85618574f7] === Token Acquisition (InteractiveRequest) started:
     Scopes: offline_access https://outlook.office.com/SMTP.Send
    Authority Host: login.microsoftonline.com
MSAL Info False MSAL 4.50.0.0 MSAL.Desktop 4.8 or later Windows 10 Pro [2023-03-06 23:25:43Z - c5490327-1e27-4d0c-bf7b-ff85618574f7] [Instance Discovery] Instance discovery is enabled and will be performed
MSAL Info False MSAL 4.50.0.0 MSAL.Desktop 4.8 or later Windows 10 Pro [2023-03-06 23:25:43Z - c5490327-1e27-4d0c-bf7b-ff85618574f7] [Region discovery] Not using a regional authority. 
MSAL Info False MSAL 4.50.0.0 MSAL.Desktop 4.8 or later Windows 10 Pro [2023-03-06 23:25:43Z - c5490327-1e27-4d0c-bf7b-ff85618574f7] Using legacy embedded browser.
MSAL Info False MSAL 4.50.0.0 MSAL.Desktop 4.8 or later Windows 10 Pro [2023-03-06 23:25:49Z - c5490327-1e27-4d0c-bf7b-ff85618574f7] [Legacy WebView] Redirect URI was reached. Stopping WebView navigation...
MSAL Info False MSAL 4.50.0.0 MSAL.Desktop 4.8 or later Windows 10 Pro [2023-03-06 23:26:07Z - c5490327-1e27-4d0c-bf7b-ff85618574f7] An authorization code was retrieved from the /authorize endpoint. 
MSAL Info False MSAL 4.50.0.0 MSAL.Desktop 4.8 or later Windows 10 Pro [2023-03-06 23:26:07Z - c5490327-1e27-4d0c-bf7b-ff85618574f7] Exchanging the auth code for tokens. 
MSAL Info False MSAL 4.50.0.0 MSAL.Desktop 4.8 or later Windows 10 Pro [2023-03-06 23:26:07Z - c5490327-1e27-4d0c-bf7b-ff85618574f7] === InteractiveParameters Data ===
LoginHint provided: True
User provided: True
UseEmbeddedWebView: NotSpecified
ExtraScopesToConsent: 
Prompt: no_prompt
HasCustomWebUi: False

MSAL Info False MSAL 4.50.0.0 MSAL.Desktop 4.8 or later Windows 10 Pro [2023-03-06 23:26:07Z - c5490327-1e27-4d0c-bf7b-ff85618574f7] Checking client info returned from the server..
MSAL Error False MSAL 4.50.0.0 MSAL.Desktop 4.8 or later Windows 10 Pro [2023-03-06 23:26:07Z - c5490327-1e27-4d0c-bf7b-ff85618574f7] Returned user identifiers do not match the sent user identifier
MSAL Error False MSAL 4.50.0.0 MSAL.Desktop 4.8 or later Windows 10 Pro [2023-03-06 23:26:07Z - c5490327-1e27-4d0c-bf7b-ff85618574f7] 
MSAL Error False MSAL 4.50.0.0 MSAL.Desktop 4.8 or later Windows 10 Pro [2023-03-06 23:26:08Z - c5490327-1e27-4d0c-bf7b-ff85618574f7] Exception type: Microsoft.Identity.Client.MsalClientException
, ErrorCode: user_mismatch

   at Microsoft.Identity.Client.Internal.Requests.RequestBase.ValidateAccountIdentifiers(ClientInfo fromServer)
   at Microsoft.Identity.Client.Internal.Requests.RequestBase.<CacheTokenResponseAndCreateAuthenticationResultAsync>d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Identity.Client.Internal.Requests.InteractiveRequest.<ExecuteAsync>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Identity.Client.Internal.Requests.RequestBase.<RunAsync>d__12.MoveNext()

Which version of MSAL.NET are you using? MSAL.NET 4.45-50

Platform .NET 4.7.1

What authentication flow has the issue?

Other?

Is this a new or existing app?

Repro

try
{
    var authResult = await app.AcquireTokenInteractive(scopes)
        .WithAccount(account) //  cached account selected by application logic
        .ExecuteAsync(ct);
}
catch (MsalException msalex)
{
    // Exception caught here, error code user_mismatch
}

Expected behavior If an account is provided, I expect that this account will be preselected (i.e., a default) in the account chooser, or depending on the prompt provided, request the user logs into the account directly. If the user chooses another account from the dialog, AcquireTokenInteractive should succeed and report the change in selected user in the authentication result as required.

Actual behavior Microsoft.Identity.Client.Internal.Requests.RequestBase.ValidateAccountIdentifiers throws MsalClientException if the token response was for a client account which did not match that provided using AcquireTokenInteractiveParameterBuilder.WithAccount.

Possible solution If the interactive UI has allowed the user to choose another account and they do so, the response validation should skip the account identifier check. I presume this is probably only really useful for a silent token acquisition (hinted at in #2284, now closed). Alternatively, as the token acquisition seems to be a separate step, perhaps it would make more sense to verify the response client information against that which was in the token request, instead of the client account information provided to AcquireTokenInteractive?

Additional context / logs / screenshots / links to code The particular example which first triggered this error was a cached account for an Azure tenant which no longer exists, so the interactive UI could not complete the login with this user anyway. The only option was to log in with another account.

bgavrilMS commented 1 year ago

Agreed, this is a bug.

Workaround: use WithLoginHint instead of WithAccount

rayluo commented 1 year ago

Agreed, this is a bug.

Does that also mean the WithAccount() shall no longer throw this exception?