I'm implementing Azure AD B2C authentication in my .NET MAUI app using MSAL.NET. My .NET MAUI app targets .NET 8 and I'm using Microsoft.Identity.Client.Extensions.Msal
version 4.66.0
.
My app uses the AppShell
and upon start, it hits the InitializeAsync()
method of my StartupPage.cs
. The first thing I do in InitializeAsync()
is to make the following call:
var authenticatedUser = await _authService.IsAuthenticated();
. This method looks like this:
public async Task<User> IsAuthenticated()
{
await PublicClientSingleton.Instance.AcquireTokenSilentAsync();
var claims = PublicClientSingleton.Instance.MSALClientHelper.AuthResult.ClaimsPrincipal.Claims; // This throws that error!
...
}
And this is where the System.InvalidOperation
exception is thrown with the message:
System.InvalidOperationException: On Android, you have to specify the current Activity from which the browser pop-up will be displayed using the WithParentActivityOrWindow method.
BTW, this is what my MainActivity.cs
file looks like under Android
in Platforms
folder:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// configure platform specific params
PlatformConfig.Instance.RedirectUri = $"msal{PublicClientSingleton.Instance.MSALClientHelper.AzureADB2CConfig.ClientId}://auth";
PlatformConfig.Instance.ParentWindow = this;
// Initialize MSAL and platformConfig is set
_ = Task.Run(async () => await PublicClientSingleton.Instance.MSALClientHelper.InitializePublicClientAppAsync()).Result;
}
Any suggestions on how I can address this issue?
The code I used to implement MSAL.NET in my .NET MAUI app came from this Microsoft repo: https://github.com/Azure-Samples/ms-identity-dotnetcore-maui
Someone had already posted the answer to this issue here: https://github.com/SyncfusionExamples/Authenticate-.NET-MAUI-App-with-Azure-AD/issues/1#issuecomment-1576183450
I think Microsoft team needs to update their code in the Azure Samples GitHub repo in the first link I provided.
Here's the solution: it looks like a small modification is necessary for it to work on Android. I added the following conditional method call in InitializePublicClientAppAsync()
method in MSALClientHelper
. Please notice that the added line is for Android only, hence the condition:
public async Task<IAccount> InitializePublicClientAppAsync()
{
// Initialize the MSAL library by building a public client application
this.PublicClientApplication = this.PublicClientApplicationBuilder
.WithRedirectUri($"msal{PublicClientSingleton.Instance.MSALClientHelper.AzureADB2CConfig.ClientId}://auth")
#if ANDROID
.WithParentActivityOrWindow(() => Platform.CurrentActivity) // This is needed for Android
#endif
.Build();
await AttachTokenCache();
return await FetchSignedInUserFromCache().ConfigureAwait(false);
}