Azure DevOps client libraries migrated to MSAL

Lubomir Sokolovsky

The Microsoft.VisualStudio.Services.InteractiveClient library is a public NuGet package that takes care of authenticating to Azure DevOps Services. It abstracts away the acquisition, management and refreshing of authentication tokens, so developers can focus on their goals and stay productive.

Historically, the interactive client library has been dependent on the Microsoft.IdentityModel.Clients. ActiveDirectory (or ADAL, for short) to authenticate against Azure Active Directory. With ADAL coming close to the end of its lifecycle, we have updated the interactive client to use a new authentication library – Microsoft.Identity.Client, also known as MSAL.

Breaking changes

The migration demanded reworking large parts of the interactive client, leading to several breaking changes. Arguably, the most prominent change is the shift from ADAL’s resources to MSAL’s scopes. In previous versions of interactive client, you would authenticate like this:

using Microsoft.VisualStudio.Services.Client;
...
// All the provided values are samples
var accountProvider = new VSAccountProvider("vsInstanceName");
var resource = "https://www.contoso.com";
var tenantId = new Guid().ToString();
var upn = "jane.doe@contoso.com";
accountProvider.AcquireTokenAsync(resource, tenantId, upn, WinFormsButton.Handle);

Starting with version 19.209.0-preview you can utilize the more robust and flexible scope parameters:

using Microsoft.VisualStudio.Services.Client;
...
// All the provided values are samples
var accountProvider = new VSAccountProvider("vsInstanceName");
var scopes = new string[] { "https://www.contoso.com/.default" };
var tenantId = new Guid().ToString();
var upn = "jane.doe@contoso.com";
accountProvider.AcquireTokenAsync(scopes, tenantId, upn, WinFormsButton.Handle);

Usually, you will be fine using the default scope. To help you with the transition from resources to scopes, you can add this simple helper method:

public static string[] GetDefaultScopes(string resource)
{
    var defaultScope =  resource.EndsWith("/")
        ? $"{resource}.default"
        : $"{resource}/.default";
    return new string[] { defaultScope };
}

Additional changes involve the removal of all “ADAL” references to provide more generic names of methods, delegates, properties, and fields. This includes the optional registry keys adaluri and AdalExtraParametersRegistryOverride, which have been renamed to accounturi and ExtraParametersRegistryOverride, respectively. Moreover, several method overloads have been unified into a single method with a list of optional named parameters.

Changes to Microsoft.TeamFoundationServer.ExtendedClient

Hand in hand with our push towards using MSAL, we have removed the ADAL references from another client library, namely Microsoft.TeamFoundationServer.ExtendedClient. The extended client had several deprecated methods and classes dependent on ADAL. Starting with the version 19.207.0-preview, those methods and classes have been fully removed along with the reference to Microsoft.IdentityModel.Clients.ActiveDirectory.

How to get started

To get your hands on the newest changes, download the latest version from NuGet.org. You can find examples of how to use the libraries in our GitHub samples.

Please comment below with any questions, comments, or issues you may have. We take your input seriously and read every bit of feedback. We are excited for you all to try this out and tell us what you think!