Building desktop, mobile, and web applications with one code base is finally possible! With .NET MAUI, you can build your native UI in .NET with XAML and C#, and then run that same single code base on all these target platforms:
- Windows using WinUI
- macOS with Mac Catalyst apps
- iOS and Android apps on phones
In this blog, we will see how to create a .NET MAUI application that authenticates users using Azure Active Directory on Windows and Android platforms. Authentication is the process of identifying users who request access to a system. This often determines user identity according to their credentials. Authentication keeps unauthorized users from accessing sensitive information, thus blocking cyber criminals on unsecured systems from accessing and stealing information.
To authenticate a .NET MAUI application using Azure AD:
- Register the application in Azure AD.
- Create a .NET MAUI program to use the registered application to authenticate.
Easily build cross-platform mobile and desktop apps with the flexible and feature-rich controls of the Syncfusion .NET MAUI platform.
Register the application in Azure AD
First, register the Web API in your Azure Active Directory tenant and add a scope by following these steps:
- Sign in to the Azure portal.
- If you have access to multiple tenants, use the Directories + subscriptionsfilter in the top menu to switch to the tenant where you want to register the application.
- Search for and select Azure Active Directory.
- Under Manage, select App registrations -> New registration.
- Name: Enter a name for your application. For example, MyMauiApp. Users of your app will see this name. You can change it later.
- Supported account types: Accounts in any organizational directory (any Azure AD directory—multitenant) and personal Microsoft accounts (e.g., Skype, Xbox).
- Select Register.
- Under Authentication, provide the redirection URI.
- Select Overview.
- Note the Application (client) ID in the Essentials section, as you’ll need this value to configure the backend service later. This will be referred to as the Web API Application ID.
Create a .NET MAUI Program
- Create a new .NET MAUI project referring to the MS documentation, Build your first app. Here, I am going to name the project MauiAuthApp.
- Install the Microsoft.Identity.Client, System.IdentityModel.Tokens.Jwt, and CommunityToolkit.Maui NuGet packages in the project.
The Microsoft.Identity.Client package is used in the following scenarios:- Web app that signs in users.
- Web app that signs in users and calls a web API on their behalf.
- Protected web API that only authenticated users can access.
- Protected web API that calls another (downstream) web API on behalf of the signed-in user.
The System.IdentityModel.Tokens.Jws package is required for the security token designed for representing a JSON web token (JWT).
The CommunityToolkit.Maui package is used to display the authentication message in a toast.
Syncfusion .NET MAUI controls are well-documented, which helps to quickly get started and migrate your Xamarin apps.
Read NowCreate a class named Constants to assign the client ID and the scope values. Refer to the following code.
namespace MauiAuthApp; public static class Constants { //The Application or Client ID will be generated while registering the app in the Azure portal. Copy and paste the GUID. public static readonly string ClientId = "3bf5e165-a671-44e9-a412-22f13c737078"; //Leaving the scope to its default values. public static readonly string[] Scopes = new string[] { "openid", "offline_access" }; }
- Modify the manifest files with the following code. For Android, open AndroidManifest.xml.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"> <application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true"> <activity android:name="microsoft.identity.client.BrowserTabActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="msal35610457-7107-4d3d-a3d9-f1f7ffaaf904" android:host="auth" /> </intent-filter> </activity> </application> <queries> <package android:name="com.azure.authenticator" /> <package android:name="com.companyname.mauiauthapp" /> <!-- This value should be copied from the MauiAuthApp.csproj file --> <package android:name="com.microsoft.windowsintune.companyportal" /> </queries> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> </manifest>
Note: android:scheme starts with msal and continues with the client ID from the app registration at the Azure portal. Also, the application ID is used in the MAUI app’s project file. For example, refer to the screenshot of the MauiAuthApp.csproj file.
- You need to override some methods to receive a callback from the identity server. For Android, open Android/MainActivity.cs and override the OnActivityResult method.
using Android.App; using Android.Content; using Android.Content.PM; using Microsoft.Identity.Client; namespace MauiAuthApp; [Activity(Theme = "@style/Maui.SplashTheme", Exported = true, MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)] public class MainActivity : MauiAppCompatActivity { protected override void OnActivityResult(int requestCode, Result resultCode, Intent? data) { base.OnActivityResult(requestCode, resultCode, data); AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(requestCode, resultCode, data); } }
You also need to set the activity attribute Exported = true.
- Next, create the AuthService class. Refer to the following code.
using Microsoft.Identity.Client; namespace MauiAuthApp; public class AuthService { private readonly IPublicClientApplication authenticationClient; // Providing the RedirectionUri to receive the token based on success or failure. public AuthService() { authenticationClient = PublicClientApplicationBuilder.Create(Constants.ClientId) .WithRedirectUri($"msal{Constants.ClientId}://auth") .Build(); } // Propagates notification that the operation should be cancelled. public async Task<AuthenticationResult> LoginAsync(CancellationToken cancellationToken) { AuthenticationResult result; try { result = await authenticationClient .AcquireTokenInteractive(Constants.Scopes) .WithPrompt(Prompt.ForceLogin) //This is optional. If provided, on each execution, the username and the password must be entered. .ExecuteAsync(cancellationToken); return result; } catch (MsalClientException) { return null; } } }
- Prepare the UI to use the AuthService. Add a login button to the MainPage.xaml. The following code is the default code in the MainPage.xaml, where the label and the button elements are modified. Here, a Login button is added to perform the authentication.
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="MauiAuthApp.MainPage"> <ScrollView> <VerticalStackLayout Spacing="25" Padding="30,0" VerticalOptions="Center"> <Image Source="dotnet_bot.png" SemanticProperties.Description="Cute dot net bot waving hi to you!" HeightRequest="200" HorizontalOptions="Center" /> <Label Text="Hello, Everyone!" SemanticProperties.HeadingLevel="Level1" FontSize="32" HorizontalOptions="Center" /> <Label Text="Authenticate .Net MAUI app with Azure Active Directory!" SemanticProperties.HeadingLevel="Level2" SemanticProperties.Description="Welcome to dot net Multi platform App UI" FontSize="18" HorizontalOptions="Center" /> <Button Text="Login" SemanticProperties.Hint="Login" Clicked="OnLoginClicked" HorizontalOptions="Center" /> </VerticalStackLayout> </ScrollView> </ContentPage>
- Add the click event handler in the MainPage.xaml.cs file. Use the following code to complete the application creation.
using CommunityToolkit.Maui.Alerts; using Microsoft.Identity.Client; using System.IdentityModel.Tokens.Jwt; using System.Text; namespace MauiAuthApp; public partial class MainPage : ContentPage { int count = 0; public MainPage() { InitializeComponent(); } private async void OnLoginClicked(object sender, EventArgs e) { try { var authService = new AuthService(); var result = await authService.LoginAsync(CancellationToken.None); var token = result?.IdToken; // AccessToken also can be used if (token != null) { var handler = new JwtSecurityTokenHandler(); var data = handler.ReadJwtToken(token); var claims = data.Claims.ToList(); if (data != null) { var stringBuilder = new StringBuilder(); stringBuilder.AppendLine($"Name: {data.Claims.FirstOrDefault(x => x.Type.Equals("name"))?.Value}"); stringBuilder.AppendLine($"Email: {data.Claims.FirstOrDefault(x => x.Type.Equals("preferred_username"))?.Value}"); await Toast.Make(stringBuilder.ToString()).Show(); } } } catch (MsalClientException ex) { await Toast.Make(ex.Message).Show(); } } }
To make it easy for developers to include Syncfusion .NET MAUI controls in their projects, we have shared some working ones.
We have completed implementing the application! Let’s run the application to see the result.
Syncfusion .NET MAUI controls allow you to build powerful line-of-business applications.
Following is the output of the application we created. The application runs and asks for authentication details. If authenticated, you will receive the toast message that we returned. Here, we have used the Name and Email address of the user to confirm the authentication.
GitHub
You can download the complete sample to authenticate .NET MAUI apps with Azure AD. Supercharge your cross-platform apps with Syncfusion's robust .NET MAUI controls.
Conclusion
I hope you enjoyed reading this blog. This article explained the procedure to authenticate a .NET MAUI application using Azure Active Directory on Windows and Android platforms.
Syncfusion’s .NET MAUI controls were built from scratch using .NET MAUI, so they feel like framework controls. They are fine-tuned to work with a huge volume of data. Use them to build better cross-platform mobile and desktop apps!
For current customers, the new Essential Studio version is available for download from the License and Downloads page. If you are not yet a Syncfusion customer, you can always download our free evaluation to see all our controls in action.
For questions, you can contact us through our support forum, support portal, or feedback portal. We are always happy to assist you!
Comments (10)
Hi. Great article. Is there any possibility of providing the extra information needed to support IOS? Thanks
Hi Norman,
I am glad that this article is useful to you. I will make a note of your request and get it updated for iOS platform too. You can find the updated article in a week of time.
Did we ever get the iOS platform sample done?
Is something missing in MainActivity?
Error:
System.InvalidOperationException: ‘On Xamarin.Android, you have to specify the current Activity from which the browser pop-up will be displayed using the WithParentActivityOrWindow method. ‘
Hi Victoria,
Thanks for notifying the error. Please have the modified sample from the below link.
https://support.syncfusion.com/attachment/download/478777
Regards,
Paul Anderson
I get the same error as VICTORIA. But I also get Access denied when trying to go to your link with the modified example.
Hi Patrik,
We have included the fix in the GitHub location mentioned in this blog. You can check out the code and just replace the ClientId in the Constants.cs file and deploy the application.
Sample: https://github.com/SyncfusionExamples/Authenticate-.NET-MAUI-App-with-Azure-AD
What was the fix? I am getting this error when I use a version of ‘Microsoft.Identity.Client’ that doesn’t support .NET MAUI. (=4.3.0) for net7.0-ios16.1″
Any news about the iOS part? I can get through the whole process and authenticate on iOS devices, and the token is saved but i am always prompted for a password -whereas on Android goes through, so probably is there anything missing in the platform config?
I’d also like to know if there is an update for the iOS part of the tutorial?
Comments are closed.