msal_auth_plugin
msal_auth_plugin provides Microsoft authentication on Android and iOS using the native MSAL library.
It is designed to be straightforward, secure, and easy to use for Flutter developers.
Features 🚀
- Option to set one of the following brokers (Authentication middleware):
- MS Authenticator App
- Browser
- In-App WebView
- Single account mode support
- Acquire token interactively & silently
- Complete authentication result with account information
Platform Support
| Platform | Supported Version |
|---|---|
| Android | API Level 21+ (Android 5.0 and above) |
| iOS | iOS 14+ |
Setup Guide ⚙️
To implement MSAL in Flutter, you first need to set up an app in the Azure Portal and configure platform-specific settings.
➡ Follow the step-by-step guide below ⬇️
1. Create an App in Azure Portal
-
Sign in to the Azure Portal.
-
In the search bar, type App registrations and click on it.
-
Click New registration.
-
Fill in the Name field and select the desired Supported account types.
-
Click Register to create the app.
-
Once created, you will find:
- Application (client) ID
- Directory (tenant) ID
These values are required later in your Dart code.
2. Configure Platform-Specific Settings
After registration:
- Go to Manage → Authentication → Add platform.
- Add platform configurations for:
- Android
- iOS/macOS
- Configure redirect URIs and other settings as per your platform needs.
Android Setup – Azure Portal ⚙️
For Android, you need to provide your package name and signature hash.
To generate a signature hash in Flutter, run the following commands from your project’s android folder:
🔹 Debug build:
keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore -storepass android -keypass android | openssl sha1 -binary | openssl base64
🔹 Release build:
keytool -exportcert -alias upload -keystore app/upload-keystore.jks | openssl sha1 -binary | openssl base64
- Ensure you have
upload-keystore.jksfile placed insideandroid/appfolder. Follow the Flutter's documentationBuild and release an Android appto create a release setup.
Register both signature hash in Azure's Android Platform configurations.
iOS Setup - Azure portal
- You need to provide only
Bundle IDof your iOS/macOS app.Redirect URIwill be generated automatically by system.
Android Configuration
This plugin offers full customization, allowing you to provide a configuration JSON file to be used during application creation & authentication.
Follow the steps below to complete the Android configuration.
Gradle repository setup (required)
MSAL depends on com.microsoft.device.display:display-mask, which is hosted on Microsoft's Duo SDK Maven feed. Add the repository to your Android project's Gradle repositories so the dependency can be resolved.
Kotlin DSL (build.gradle.kts):
allprojects {
repositories {
google()
mavenCentral()
maven {
url = uri("https://pkgs.dev.azure.com/MicrosoftDeviceSDK/DuoSDK-Public/_packaging/Duo-SDK-Feed/maven/v1")
name = "Duo-SDK-Feed"
}
}
}
Groovy (build.gradle):
allprojects {
repositories {
google()
mavenCentral()
maven {
url uri('https://pkgs.dev.azure.com/MicrosoftDeviceSDK/DuoSDK-Public/_packaging/Duo-SDK-Feed/maven/v1')
name 'Duo-SDK-Feed'
}
}
}
Notes:
- If your project uses
dependencyResolutionManagement { repositories { ... } }insettings.gradle(.kts), add the samemaven { ... }block there instead. - After adding, run:
flutter clean && flutter pub getbefore rebuilding.
Creating MSAL Configuration JSON
- Create an
msal_config.jsonfile in theandroid/app/src/main/res/rawfolder of your project and copy the JSON content from theMicrosoft default configuration file. - Below is an example JSON format you can use for configuration:
{
"client_id" : "YOUR APPLICATION CLIENT ID",
"authorization_user_agent" : "DEFAULT",
"broker_redirect_uri_registered": true,
"redirect_uri" : "msauth://<APP_PACKAGE_NAME>/<BASE64_ENCODED_PACKAGE_SIGNATURE>",
"account_mode": "SINGLE",
"authority": "https://login.microsoftonline.com/<TENANT_ID>",
"authorities" : [
{
"type": "AAD",
"audience": {
"type": "AzureADandPersonalMicrosoftAccount",
"tenant_id": "YOUR TENANT_ID"
}
}
]
}
- If you are using a broker, set broker_redirect_uri_registered to
true; if not, set it tofalse. - account_mode currently only supports SINGLE. MULTIPLE support will be added in the future.
- authorization_user_agent can be set to one of the following values:
"authorization_user_agent": "BROWSER"
"authorization_user_agent": "WEBVIEW"
Add Internet and Network State permission in AndroidManifest.xml
This permission declaration is required for browser-delegated authentication:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Add BrowserTabActivity in AndroidManifest.xml
If you use the Browser or Authenticator app for authentication, you must specify BrowserTabActivity within the <application> tag in your AndroidManifest.xml file.
<application>
...
<activity android:name="com.microsoft.identity.client.BrowserTabActivity">
<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:host="com.example.msal_auth_example"
android:path="/<BASE64_ENCODED_PACKAGE_SIGNATURE>"
android:scheme="msauth" />
</intent-filter>
</activity>
</application>
- Replace
hostwith your app's package name andpathwith thebase64 signature hashthat was generated earlier.
Add Required Packages for Broker Authentication
If you are using a broker for authentication, make sure to add the following packages in your AndroidManifest.xml:
<package android:name="com.azure.authenticator" />
<package android:name="com.microsoft.windowsintune.companyportal" />
iOS Configuration
-
Add the following keychain groups to your project capabilities:
com.microsoft.adalcachecom.microsoft.identity.universalstorage

Without these keychain groups, your app will not be able to open the
Microsoft Authenticatorapp if specified as a broker. Additionally, thelogoutmethod will throw an exception because the account cannot be found in the cache.
Info.plist Modification
- Add your application's redirect URI scheme to your
Info.plistfile:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>msauth.$(PRODUCT_BUNDLE_IDENTIFIER)</string>
</array>
</dict>
</array>
- Add
LSApplicationQueriesSchemesto allow theMicrosoft Authenticatorapp to be used as a broker for authentication.This is not required when usingSafari BrowserorWebViewas the broker.
<key>LSApplicationQueriesSchemes</key>
<array>
<string>msauthv2</string>
<string>msauthv3</string>
</array>
- If you use
Broker.msAuthenticatorafter declaring the above schemes but the Authenticator app is not installed on the iPhone, the authentication will fall back to usingSafari Browser.
Handle callback from MSAL
- Your app needs to handle login success callback if app uses
Microsoft Authenticatorapp ORSafari Browserfor authentication.WebViewdoes not require it. - Your app needs to handle the login success callback if it uses the
Microsoft Authenticatorapp orSafari Browserfor authentication.WebViewdoes not require this callback.
AppDelegate.swift
import MSAL
override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
return MSALPublicClientApplication.handleMSALResponse(url, sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String)
}
- Refer to the
`AppDelegate.swift`file in the example app for more clarity.
Implementation
This section covers how to write the Dart code to set up an MSAL application in Flutter and authenticate the user.
class MsalAuthService {
// Define the redirect URI based on the platform (iOS or Android)
// This URI must match what you registered in Azure AD for your app
final String redirectUri = Platform.isIOS
? dotenv.env['IOS_URI']! // iOS redirect URI from .env file
: dotenv.env['ANDROID_URI']!; // Android redirect URI from .env file
/// Initialize the MSAL authentication service
Future<void> init() async {
// Read clientId and tenantId from .env
final String? clientId = dotenv.env['CLIENT_ID'];
final String? tenantId = dotenv.env['TENANT_ID'];
// Throw exceptions if required environment variables are missing
if (clientId == null || clientId.isEmpty) {
throw Exception("MSAL INIT_ERROR: CLIENT_ID missing from .env");
}
if (tenantId == null || tenantId.isEmpty) {
throw Exception("MSAL INIT_ERROR: TENANT_ID missing from .env");
}
// Initialize MSAL with the required parameters
// - clientId: Application ID from Azure AD
// - authority: URL for your tenant, e.g., https://login.microsoftonline.com/<tenantId>
// - redirectUri: Redirect URI registered in Azure AD
// - tanantId: (likely a typo, should be 'tenantId') Tenant ID from Azure AD
await MsalAuth.initialize(
clientId: clientId,
authority: "https://login.microsoftonline.com/$tenantId",
redirectUri: redirectUri,
tanantId: tenantId, // ⚠️ likely a typo in the code, should be tenantId
);
}
/// Perform interactive sign-in
Future<AuthResult> signIn() async {
try {
// Attempt to authenticate the user interactively
return await _performInteractiveAuth();
} catch (e) {
// Log any unexpected errors and rethrow them
log('Unexpected sign-in error: $e');
rethrow;
}
}
/// Internal method to perform interactive authentication
Future<AuthResult> _performInteractiveAuth() async {
// Call MSAL to sign in interactively
final AuthResult result = await MsalAuth.signIn();
// Log tokens for debugging (avoid in production)
log("ID Token: ${result.idToken}");
log('Auth result: ${result.accessToken}');
return result;
}
/// Acquire a token silently if the user has already signed in
/// Useful for refreshing access without user interaction
Future<AuthResult> acquireTokenSilent() {
return MsalAuth.acquireTokenSilent();
}
/// Sign out the current user
Future<void> signOut() async {
MsalAuth.signOut();
}
/// Get information about the currently signed-in user
Future<Map<String, dynamic>?> getCurrentAccount() async {
final user = await MsalAuth.getCurrentAccount();
// Log the current user info for debugging
log("Current user: $user");
return user;
}
}
Reference Documentation
For detailed platform-specific configuration, refer to the official Microsoft Azure documentation:
- Android MSAL setup: Microsoft Authentication Library (MSAL) for Android
- iOS MSAL setup: Microsoft Authentication Library (MSAL) for iOS
License
This project is licensed under the MIT License - see the LICENSE file for details.