I have the following client code to fetch a token from Azure B2C endpoint:
public static async Task<AuthenticationResult> AcquireTokenAsync(this IPublicClientApplication publicClientApp)
{
try
{
var accounts = await publicClientApp.GetAccountsAsync();
return await Task.Run(() =>
publicClientApp
.AcquireTokenInteractive(apiScopes)
.WithAccount(accounts.FirstOrDefault())
.WithPrompt(Prompt.ForceLogin)
.ExecuteAsync());
}
catch (MsalClientException ex)
{
if (ex.ErrorCode.Equals("authentication_canceled"))
{
log.Info("Authentication was cancelled");
}
log.Error("Error in login sequence", ex);
throw;
}
}
Where publicClientApp
is created as such:
app = PublicClientApplicationBuilder.Create(ClientId)
.WithB2CAuthority(Authority)
.Build();
I would like to be able to distinguish different “error code” situations, taking into account MFA. So far I have been able to capture when user cancels/closes the authentication window – which throws MsalClientException with an error code authentication_canceled
.
Next I would like to capture the failed MFA verification, and by debugging the code I can see that after failing the verification enough times, the AcquireTokenInteractive throws:
Microsoft.Identity.Client.MsalClientException:
'The browser based authentication dialog failed to complete. Reason: The server encountered an unexpected condition that prevented it from fulfilling the request.'
With an error code: authentication_ui_failed
Stack trace:
at Microsoft.Identity.Client.Platforms.net45.WebUI.<AcquireAuthorizationAsync>d__20.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Identity.Client.Internal.Requests.InteractiveRequest.<AcquireAuthorizationAsync>d__10.MoveNext()
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()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Identity.Client.Internal.Requests.RequestBase.<RunAsync>d__14.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Identity.Client.ApiConfig.Executors.PublicClientExecutor.<ExecuteAsync>d__2.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at MyProject.AzureB2CIntegration.PublicClientApplicationExtensions.<AcquireTokenAsync>d__4.MoveNext() in C:ProjectsMyCommonAzureB2CIntegrationPublicClientApplicationExtensions.cs:line 23
However, when inspecting the traffic on Fiddler, I get a more sensible error response from B2C:
status=500 Internal Server Error
error=server_error
error_description=AADB2C90151: User has exceeded the maximum number for retries for multi-factor authentication.
As I’m new to Azure B2C / Microsoft.Identity – is there a way to get a more detailed error information (like the one from Fiddler) from AcquireTokenInteractive in such case?