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:
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:
First, register the Web API in your Azure Active Directory tenant and add a scope by following these steps:
The CommunityToolkit.Maui package is used to display the authentication message in a toast.
Create 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" }; }
<?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.
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.
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; } } }
<?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>
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(); } } }
We have completed implementing the application! Let’s run the application to see the result.
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.
You can download the complete sample to authenticate .NET MAUI apps with Azure AD.
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!