A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
The failure pattern matches the silent-first flow reaching interactive sign-in, which is expected when AcquireTokenSilent throws MsalUiRequiredException. That exception means interactive authentication is required because the cache cannot satisfy the request or extra user interaction is needed.
For a .NET MAUI app, the most important fixes are:
- Keep the silent-first pattern
The
AcquireTokenSilentcall should stay first, andMsalUiRequiredExceptionshould fall back toAcquireTokenInteractive. That part of the flow is correct. - On Android, always pass the current activity to interactive sign-in
AcquireTokenInteractivemust use:
Omitting the Android parent activity causes a runtime crash because MSAL cannot find a parent window for the sign-in UI..WithParentActivityOrWindow(Platform.CurrentActivity) - Ensure
Platform.CurrentActivityis initialized InMainActivity.OnCreate,Platform.Init(this, savedInstanceState)must be called soPlatform.CurrentActivityis set correctly before interactive sign-in runs. - Do not create a new page just to supply a parent window
This code is a likely problem:
The parent window should be the platform window/activity configured by the app, not a newly created MAUI page instance. Use the platform-specific parent window that is initialized during app startup..WithParentActivityOrWindow(new MainPage(...)) - For Android, verify the redirect URI and activity wiring
The app registration must include an Android redirect URI in this format:
The Android activity handling the auth callback must use the same scheme andmsal{ClientId}://authauthhost in its intent filter. - Set the Android parent window during startup
In the MAUI Android setup, the current activity should be assigned as the parent window for authentication operations during
MainActivity.OnCreate.
A safer shape for the interactive call is:
return await this.PublicClientApplication
.AcquireTokenInteractive(scopes)
.WithLoginHint(existingAccount?.Username ?? string.Empty)
#if ANDROID
.WithParentActivityOrWindow(Platform.CurrentActivity)
#endif
.ExecuteAsync();
If embedded web view is required, keep it, but still use the correct parent activity/window.
Also note:
- If
AcquireTokenSilent()fails withMsalUiRequiredException, that does not mean the app is broken by itself. It means the app must continue with interactive sign-in. - If the app is failing only when a user was previously signed in, the issue is more likely the interactive UI host/window setup than the silent token call.
Recommended checks in order:
- In
Platforms/Android/MainActivity.cs, confirmPlatform.Init(this, savedInstanceState)is called. - Confirm interactive Android sign-in uses
.WithParentActivityOrWindow(Platform.CurrentActivity). - Remove any use of
new MainPage(...)as the parent window. - Confirm the app registration redirect URI exactly matches
msal{ClientId}://auth. - Confirm the Android auth callback activity intent filter uses the same client ID-based scheme and
authhost. - Keep
AcquireTokenSilentfirst, and only fall back to interactive onMsalUiRequiredException.
One code issue should also be corrected:
catch (MsalException msalEx)
{
Debug.WriteLine($"Error Acquiring Token interactively:{Environment.NewLine}{msalEx}");
throw;
}
Using throw; preserves the original stack trace.