-
Notifications
You must be signed in to change notification settings - Fork 214
Leveraging brokers on Android and iOS
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 (is it really outlook which calls me?). The way it works is when an application calls the broker, it passes its redirect url, and the broker verifies it:
- On iOS, the redirect URL is, for instance,
ms-word://com.msft.com
, the broker parses and gets the appId (after the //) and verifies it's the same as the appId of the calling app, which it knows (by the OS). - On Android the redirect URLs have the following shape
msauth://com.msft.word/<base64URL encoded hash>
.
- On iOS, the redirect URL is, for instance,
To enable one of these features, the application developers need to set the UseBroker
Boolean to true in the platform parameters. They also need to implement a delegate to react to the broker calling back the application as described in Platform parameters properties specific to brokers on Android and iOS
Things are slightly different on iOS and Android. here are the details:
If your Xamarin.iOS app requires conditional access or certificate authentication (currently in preview) support, you must set up your AuthenticationContext and redirectURI to be able to talk to the Microsoft Authenticator app. Make sure that your Redirect URI and application's bundle id is all in lower case.
Broker support is enabled on a per-authentication-context basis. It is disabled by default. You must set the useBroker
flag to true in the PlatformParameters
constructor if you wish ADAL.NET to call the broker:
public PlatformParameters(UIViewController callerViewController, bool useBroker)
When ADAL.NET calls the broker, it will call back to your application, through the OpenUrl
method of AppDelegate. Since ADAL waits for the token from the broker, your application needs to cooperate to call ADAL.NET back. You will do this by updating the AppDelegate.cs file to override the method below.
public override bool OpenUrl(UIApplication application, NSUrl url, string sourceApplication, NSObject annotation)
{
if (AuthenticationContinuationHelper.IsBrokerResponse(sourceApplication))
{
AuthenticationContinuationHelper.SetBrokerContinuationEventArgs(url);
}
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 ADAL.Net.
ADAL.Net 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. We recommend making the URL scheme fairly unique to minimize the chances of another app using the same URL scheme.
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>com.mycompany.myapp</string>
<key>CFBundleURLSchemes</key>
<array>
<string>mytestiosapp</string>
</array>
</dict>
</array>
ADAL 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. You will need to add “msauth” to the LSApplicationQueriesSchemes section of your info.plist file.
<key>LSApplicationQueriesSchemes</key>
<array>
<string>msauth</string>
</array>
This adds extra requirements on your redirect URI. Your redirect URI must be in the proper form.
<app-scheme>://<your.bundle.id>
ex: mytestiosapp://com.mycompany.myapp
This Redirect URI needs to be registered on the app registration portal (https://portal.azure.com) as a valid redirect URI for your application. Additionally a second "msauth" form needs to be registered to handle certificate authentication in Azure Authenticator.
msauth://code/<broker-redirect-uri-in-url-encoded-form>
AND
msauth://code/<broker-redirect-uri-in-url-encoded-form>/
ex: msauth://code/mytestiosapp%3A%2F%2Fcom.mycompany.myapp and msauth://code/mytestiosapp%3A%2F%2Fcom.mycompany.myapp/
If your Xamarin.Android app or your app users requires conditional access or certificate authentication support, you must set up your AuthenticationContext and redirectURI to be able to talk to the Microsoft Authenticator app OR the Company Portal app. Both are brokers on Android. Make sure that your Redirect URI and application's bundle id is all in lower case.
Leveraging a broker is enabled on a per-authentication-context basis. It is disabled by default. You must set the useBroker
flag to true in PlatformParameters
constructor if you wish ADAL to call to broker:
public PlatformParameters(Activity callerActivity, bool useBroker)
public PlatformParameters(Activity callerActivity, bool useBroker, PromptBehavior promptBehavior)
If you target Android versions lower than 23, calling app requires having the following permissions declared in the application manifest(http://developer.android.com/reference/android/accounts/AccountManager.html):
- GET_ACCOUNTS
- USE_CREDENTIALS
- MANAGE_ACCOUNTS
If your application targets Android 23 or above, the USE_CREDENTIALS and MANAGE_ACCOUNTS permissions have been deprecated and GET_ACCOUNTS is under protection level "dangerous". Your app is responsible for requesting the runtime permission for GET_ACCOUNTS. You can reference Runtime permission request for API 23.
ADAL 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. We recommend making the URL scheme fairly unique to minimize the chances of another app using the same URL scheme.
You can call the generateRedirectUriForBroker.ps1
script (requires updates from the developer to fill in values and details about the app) to compute the redirect uri.
This Redirect URI needs to be registered on the app registration portal (https://portal.azure.com) 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 ADAL.
While debugging, you may encounter an ADAL 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.
The following methods demonstrate how you can get the current redirect URI for the APK
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)
{
try
{
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.
}
}
catch (Exception ex)
{
//Handle Exception
}
return null;
}
When ADAL.NET calls the broker, it will call back your application, through the OnActivityResult
method of your Android application MainActivity class. Since ADAL waits for the token from the broker, your application needs to cooperate to call ADAL.NET back. You will do this by updating the MainActivity.cs file to the override method below.
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
AuthenticationAgentContinuationHelper.SetAuthenticationAgentContinuationEventArgs(requestCode, resultCode, data);
}
This method is invoked when the activity receives a callback from the webview or the broker application. This code snippet is required to complete the authentication process initiated by ADAL.NET
When performing a silent call to fetch a token, ADAL must communicate with the Broker to find out which broker account to fetch a token for. ADAL uses the information you pass in as UserIdentifier to locate the account.
// perform an interactive auth first to get a result
_userName = result.UserInfo.DisplayableId; // this is in UPN (email) format, which the matches the account name on the broker
// later, in silent calls
var userId = new UserIdentifier(_userName, UserIdentifierType.OptionalDisplayableId);
AuthenticationResult result = await _ctx
.AcquireTokenSilentAsync(
resource,
clientId,
userId,
new PlatformParameters(this, true))
.ConfigureAwait(false);
- You have configured the use of the broker, but instead of the broker (Authenticator or Company Portal) popping up, the regular browser pops up. This can happen if ADAL is not able to find or invoke the broker, permissions are not set etc. Please enable logging and inspect the logs to find the root cause.
- Home
- Why use ADAL.NET?
- Register your app with AAD
- AuthenticationContext
- Acquiring Tokens
- Calling a protected API
- Acquiring a token interactively
- Acquiring tokens silently
- Using Device Code Flow
- Using Embedded Webview and System Browser in ADAL.NET and MSAL.NET
- With no user
- In the name of a user
- on behalf of (Service to service calls)
- by authorization code (Web Apps)
- Use async controller actions
- Exception types
- using Broker on iOS and Android
- Logging
- Token Cache serialization
- User management
- Using ADAL with a proxy
- Authentication context in multi-tenant scenarios
- Troubleshooting MFA in a WebApp or Web API
- Provide your own HttpClient
- iOS Keychain Access