Skip to content

Leveraging the broker on iOS and Android

Travis Walker edited this page Mar 12, 2020 · 17 revisions

Why use brokers on Xamarin.iOS and Xamarin.Android applications?

On Android and iOS, brokers enable:

  • Single Sign On (SSO). Your users won't need to sign-in to each application.
  • Device identification. By accessing the device certificate which was created on the device when it was workplace joined.
  • Application identification verification. When an application calls the broker, it passes its redirect url, and the broker verifies it.

To enable one of these features, application developers need to use the WithBroker() parameter when calling the PublicClientApplicationBuilder.CreateApplication method. .WithBroker() is set to true by default. Developers will also need to follow the steps below for iOS or Android applications.

Brokered Authentication for iOS

Follow the steps below to enable your Xamarin.iOS app to talk with the Microsoft Authenticator app.

If you are targeting iOS 13, please read this important section on MSAL.NET and broker auth support for iOS 13

Step One: Enable broker support

Broker support is enabled on a per-PublicClientApplication basis. It is disabled by default. You must use the WithBroker() parameter (set to true by default) when creating the PublicClientApplication through the PublicClientApplicationBuilder.

var app = PublicClientApplicationBuilder
                .Create(ClientId)
                .WithBroker()
                .WithRedirectUri(redirectUriOnIos) // $"msauth.{Bundle.Id}://auth" (see step 6 below)
                .Build();

Step Two: Enable keychain access

To enable keychain access, your application must have a keychain access group. You can set your keychain access group by using the WithIosKeychainSecurityGroup() api when creating your application as shown below:

var builder = PublicClientApplicationBuilder
     .Create(ClientId)
      
     .WithIosKeychainSecurityGroup("com.microsoft.adalcache")
     .Build();

The Entitlements.plist should be updated to look like the following:

<dict>
  <key>keychain-access-groups</key>
  <array>
    <string>$(AppIdentifierPrefix)com.microsoft.adalcache</string>
  </array>
</dict>

Learn more on enabling keychain access.

Step Three: Update AppDelegate to handle the callback

When MSAL.NET calls the broker, the broker will, in turn, call back to your application through the OpenUrl method of the AppDelegate class. Since MSAL will wait for the response from the broker, your application needs to cooperate to call MSAL.NET back. You do this by updating the AppDelegate.cs file to override the below method.

public override bool OpenUrl(UIApplication app, NSUrl url, 
                             string sourceApplication,
                             NSObject annotation)
{
    if (AuthenticationContinuationHelper.IsBrokerResponse(sourceApplication))
    {
         AuthenticationContinuationHelper.SetBrokerContinuationEventArgs(url);
         return true;
    }
    
    else if (!AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(url))
    {	            
         return false;	              
    }
	
    return true;	 
}	        

This method is invoked every time the application is launched and is used as an opportunity to process the response from the broker and complete the authentication process initiated by MSAL.NET.

Step Four: Set a UIViewController()

Still in AppDelegate.cs, you will need to set an object window. Normally, with Xamarin iOS, you do not need to set the object window, but in order to send and receive responses from broker, you will need an object window.

To do this, you will need to do two things.

  1. In AppDelegate.cs, set the App.RootViewController to a new UIViewController(). This will make sure there is a UIViewController with the call to the broker. If it is not set correctly, you may get this error: "uiviewcontroller_required_for_ios_broker":"UIViewController is null, so MSAL.NET cannot invoke the iOS broker. See https://aka.ms/msal-net-ios-broker"
  2. On the AcquireTokenInteractive call, use the .WithParentActivityOrWindow(App.RootViewController) and pass in the reference to the object window you will use.

For example:

In App.cs:

   public static object RootViewController { get; set; }

In AppDelegate.cs:

   LoadApplication(new App());
   App.RootViewController = new UIViewController();

In the Acquire Token call:

result = await app.AcquireTokenInteractive(scopes)
             .WithParentActivityOrWindow(App.RootViewController)
             .ExecuteAsync();

Step Five: Register a URL Scheme

MSAL.NET uses URLs to invoke the broker and then return the broker response back to your app. To finish the round trip, you need to register a URL scheme for your app in the Info.plist file.

The CFBundleURLSchemes name must include msauth. as a prefix, followed by your CFBundleURLName.

$"msauth.(BundleId)"

For example: msauth.com.yourcompany.xforms

Note This will become part of the RedirectUri used for uniquely identifying your app when receiving the response from the broker.

 <key>CFBundleURLTypes</key>
    <array>
      <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>CFBundleURLName</key>
        <string>com.yourcompany.xforms</string>
        <key>CFBundleURLSchemes</key>
        <array>
          <string>msauth.com.yourcompany.xforms</string>
        </array>
      </dict>
    </array>

Step Six: LSApplicationQueriesSchemes

MSAL uses –canOpenURL: to check if the broker is installed on the device. In iOS 9, Apple locked down what schemes an application can query for.

Add msauthv2 to the LSApplicationQueriesSchemes section of the Info.plist file.

<key>LSApplicationQueriesSchemes</key>
    <array>
      <string>msauthv2</string>
      <string>msauthv3</string>
    </array>

Step Seven: Register your RedirectUri in the application portal

Using the broker adds an extra requirement on your redirectUri. The redirectUri must have the following format:

$"msauth.{BundleId}://auth"

For example:

public static string redirectUriOnIos = "msauth.com.yourcompany.XForms://auth"; 

You'll notice the RedirectUri matches the CFBundleURLSchemes name you included in the Info.plist file.

Step Seven: make sure the redirect URI is registered with your app

This Redirect URI needs to be registered on the app registration portal (https://portal.azure.com) as a valid redirect URI for your application.

Note that there is a new experience in the app registration portal to help you compute the brokered reply URI from the bundle ID:

  1. In the app registration choose Authentication and selection Try-out the new experience image

  2. Select Add platform image

  3. When the list of platforms is supported, select iOS image

  4. Enter your bundle ID as requested, and then press Register image

  5. The redirect URI is computed for you. image

Brokered Authentication for Android

Step One: Enable broker support

Broker support is enabled on a per-PublicClientApplication basis. It is disabled by default. You must use the WithBroker() parameter (set to true by default) when creating the PublicClientApplication through the PublicClientApplicationBuilder.

var app = PublicClientApplicationBuilder
                .Create(ClientId)
                .WithBroker()
                .WithRedirectUri(redirectUriOnAndroid) //(see step 4 below)
                .Build();

Step Two: Update AppDelegate to handle the callback

When MSAL.NET calls the broker, the broker will, in turn, call back to your application with the OnActivityResult() method. Since MSAL will wait for the response from the broker, your application needs to route the result to MSAL.NET. This can be achieved by routing the result to the SetAuthenticationContinuationEventArgs(int requestCode, Result resultCode, Intent data) by overriding the OnActivityResult() method as shown below

        protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
        {
            base.OnActivityResult(requestCode, resultCode, data);
            AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(requestCode, resultCode, data);
        }

This method is invoked every time the broker application is launched and is used as an opportunity to process the response from the broker and complete the authentication process initiated by MSAL.NET.

Step Three: Set an Activity

For brokered authentication to work you will need to set an activity so that MSAL can send and receive the response from broker.

To do this, you will need to provide the activity(usually the MainActivity) to the WithParentActivityOrWindow(object parent) as the parent object.

For example:

In the Acquire Token call:

result = await app.AcquireTokenInteractive(scopes)
             .WithParentActivityOrWindow((Activity)context))
             .ExecuteAsync();

Step Four: Register your RedirectUri in the application portal

MSAL uses URLs to invoke the broker and then return back to your app. To finish that round trip you need to register a URL scheme for your app. This Redirect URI needs to be registered on the Azure AAD app registration portal as a valid redirect URI for your application.

The redirect URI needed for your application is dependent on the certificate used to sign the APK.

Example: msauth://com.microsoft.xforms.testApp/hgbUYHVBYUTvuvT&Y6tr554365466=

The last part of the URI, hgbUYHVBYUTvuvT&Y6tr554365466=, is the signature that the APK is signed with, base64 encoded. However, during the development phase of your application using Visual Studio, if you are debugging your code without signing the apk with a specific certificate, Visual Studio will sign the apk for you for debugging purposes, giving the APK a unique signature for the machine that it is built on. Thus, each time you build your app on a different machine, you will need to update the redirect URI in the application’s code and the application’s registration in the azure portal in order to authenticate with MSAL.

While debugging, you may encounter an MSAL exception (or log message) stating the redirect URI provided is incorrect. This exception will also provide you with the redirect URI that you should be using with the current machine you are debugging on. You can use this redirect URI to continue developing for the time being.

Once you are ready to finalize your code, be sure to update the redirect URI in the code and on the application's registration in the azure portal to use the signature of the certificate you will be signing the APK with.

In practice this means that you have to register a redirect URI for each member of the team, plus a redirect URI for the production signed version of the APK.

You can also compute this signature yourself, similar to how MSAL does it:

        private string GetRedirectUriForBroker()
        {
            string packageName = Application.Context.PackageName;
            string signatureDigest = this.GetCurrentSignatureForPackage(packageName);
            if (!string.IsNullOrEmpty(signatureDigest))
            {
                return string.Format(CultureInfo.InvariantCulture, "{0}://{1}/{2}", RedirectUriScheme,
                    packageName.ToLowerInvariant(), signatureDigest);
            }

            return string.Empty;
        }

        private string GetCurrentSignatureForPackage(string packageName)
        {
                PackageInfo info = Application.Context.PackageManager.GetPackageInfo(packageName,
                    PackageInfoFlags.Signatures);
                if (info != null && info.Signatures != null && info.Signatures.Count > 0)
                {
                    // First available signature. Applications can be signed with multiple signatures.
                    // The order of Signatures is not guaranteed.
                    Signature signature = info.Signatures[0];
                    MessageDigest md = MessageDigest.GetInstance("SHA");
                    md.Update(signature.ToByteArray());
                    return Convert.ToBase64String(md.Digest(), Base64FormattingOptions.None);
                    // Server side needs to register all other tags. ADAL will
                    // send one of them.
                }
           
        }

You also have the option of acquiring the signature for your package by using the keytool with the following commands:

For Windows: keytool.exe -list -v -keystore "%LocalAppData%\Xamarin\Mono for Android\debug.keystore" -alias androiddebugkey -storepass android -keypass android

For Mac: keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64

Troubleshooting tips for Android brokered authentication

It can be a bit challenging to get the brokered authentication scenario to work properly so here are some tips on avoiding issues

  • Make sure to register your redirect URI in your application's registration in the Azure Portal. This is a very common issue that developers run into.

  • Make sure you have installed the minimum required version of either Intune Company Portal Link (Version 5.0.4689.0 or greater) or Microsoft Authenticator Link (Version 6.2001.0140 or greater). Either of these two apps can be used for brokered authentication on Android.

  • If you have installed both applications on your device, The default broker that MSAL will communicate with will be the first broker installed on the device. This means if you install Microsoft Authenticator first and then Intune Company Portal afterwards, brokered authentication will only happen on the Microsoft Authenticator.

  • If you run into issues with brokered authentication and you need more information to diagnose and resolve your issue, you have the ability to view the broker's logs which may be able to help. To view the broker logs on the Microsoft Authenticator, follow the steps below:

    1. Press the menu button on the top right corner of the app.
    2. Press "Help"
    3. Press "Send Logs"
    4. Press "View Logs"
    5. Press "Copy All" at the bottom
    6. At this point you should have the broker logs copied to the device's clipboard. The best way to debug with these logs is to email them to yourself and view them on a computer. This will make it much easier to digest the logs as opposed to looking at them on the device directly. You can also use a test editor on android to save the logs as a text file and use a USB cable to copy the file to a computer.
  • For Intune Company Portal you can follow the steps below

    1. Press the menu button on the top left corner of the app.
    2. Press "Settings"
    3. Scroll down to "Diagnostic Data" and press "Copy Logs". This will copy the broker logs to a file on SD Card that you can access with a USB cable on a conputer

    Once you have the logs you can search through them for your authentication attempts via correlation id. The correlation id is attached to every authentication request and each phase of the authentication attempts will have the correlation id attached to it. To find errors returned from the AAD authentication endpoint, you can look for "AADSTS".

Getting started with MSAL.NET

Acquiring tokens

Web Apps / Web APIs / daemon apps

Desktop/Mobile apps

Advanced topics

FAQ

Other resources

Clone this wiki locally