Improved Windows Broker Support with MSAL.NET
The Identity SDK team just released a brand-new version of the Microsoft Authentication Library (MSAL) for .NET that introduces an improved experience for developers using authentication brokers to simplify how they acquire and use tokens in their applications.
To take advantage of the new broker functionality, developers will need to use the
Microsoft.Identity.Client package from NuGet, starting with version 4.52.0.
What is a Broker
An authentication broker is an application that runs on a user’s machine that handles the authentication handshakes and token maintenance for connected accounts. As its authentication broker, the Windows operating system uses the Web Account Manager (WAM), which is supported on Windows Server 2019 and above, Windows 10, and Windows 11. It has many benefits for developers and customers alike, including:
- Enhanced security. The client application does not need to manage the refresh token which can be used to obtain new authentication tokens without the user consent.
- Feature support. With the help of the broker developers can access rich OS and service capabilities such as Windows Hello, Conditional Access Policies, and FIDO keys without writing extra scaffolding code.
- System integration. Applications that use the broker plug-and-play with the built-in account picker, allowing the user to quickly pick an existing account instead of reentering the same credentials over and over.
With the help of a broker you need to write less code to handle token-related logic while also being able to use more advanced functionality, such as Proof-of-Possession tokens. Moving forward, our team is continuing to invest in making sure that brokers are the de-facto approach to authenticate with MSAL-based applications, where possible.
What is Changing
Recently, an updated authentication broker experience was made available for Windows systems. The new broker is written in C++, is well tested, and is significantly more performant and secure. One of the biggest consumers of the new broker experience is the Microsoft 365 suite of apps.
With the introduction of the updated broker, we’ve also updated MSAL.NET to expose its capabilities under a simplified API. The improved broker experience in MSAL.NET will replace the existing broker flows by default – developers do not need to take any extra steps. An exception to this are Universal Windows Platform (UWP) applications – they will continue to use the legacy authentication broker due to Windows API limitations.
Using the New Broker
To use the new broker, developers will need to use the RuntimeBroker class, hosted in
Microsoft.Identity.Client package. Most of the frameworks supported by MSAL.NET will need that package only, with a few exceptions. See the table below for a detailed mapping.
|net48||✅||✅||✅ (not recommended)|
|netcoreapp3.1 (not recommended)||✅||✅||✅ (not recommended)|
netcoreapp3.1 target framework has reached the end of life this past December, our team will no longer offer support for applications using MSAL with the specific version of .NET Core. We recommend upgrading to the latest version where possible.
Parent Window Requirement
Specifying a parent window handle was an optional parameter when working with the legacy broker. When a parent window handle was not provided, the window for entering user credentials could pop up anywhere, making for a less than ideal experience, as the window could be obstructed by another window or displayed on a screen where the user does not expect to see it.
To mitigate the issue, starting with the latest version of MSAL.NET, specifying the parent window handle is now required when working with the Windows authentication broker. Developers will be able to specify the window they want to bind the broker popup to via
Because the new broker is not available through the UWP API surface, the function cannot be used inside a UWP application.
To get a better understanding of how to use the new broker, let’s take a look at a few examples across the matrix of supported frameworks.
var pcaBuilder = PublicClientApplicationBuilder .Create(s_clientIdForPublicApp) .WithAuthority(Authority) .WithLogging(Log, LogLevel.Verbose, true) .WithRedirectUri("http://localhost") // required for DefaultOsBrowser .WithParentActivityOrWindow(consoleWindowHandleProvider); BrokerOptions options = new BrokerOptions(BrokerOptions options = new BrokerOptions(BrokerOptions.OperatingSystems.Windows)); // Set the desired properties such as Title, ListOperatingSystemAccounts options.<desired property> = ...; pcaBuilder.WithWindowsDesktopFeatures(options); var pca = PublicClientApplicationBuilder.Create(...) .WithWindowsDesktopFeatures(options) .WithParentActivityOrWindow(consoleWindowHandleProvider) .Build(); AuthenticationResult result = pca.AcquireTokenInteractive(Scopes) .ExecuteAsync() .ConfigureAwait(false);
var pcaBuilder = PublicClientApplicationBuilder .Create(s_clientIdForPublicApp) .WithAuthority(Authority) .WithLogging(Log, LogLevel.Verbose, true) .WithRedirectUri("http://localhost") // required for DefaultOsBrowser .WithParentActivityOrWindow(consoleWindowHandleProvider); BrokerOptions options = new BrokerOptions(BrokerOptions options = new BrokerOptions(BrokerOptions.OperatingSystems.Windows)); // Set the desired properties such as Title, ListOperatingSystemAccounts options.<desired property> = ...; pcaBuilder.WithBroker(options); // this is the only line different from .net6.0 var pca = PublicClientApplicationBuilder.Create(...) .WithWindowsDesktopFeatures(options) .WithParentActivityOrWindow(consoleWindowHandleProvider) .Build(); AuthenticationResult result = pca.AcquireTokenInteractive(Scopes) .ExecuteAsync() .ConfigureAwait(false);
.NET 6.0 (Windows-specific)
If you are building a net6.0-windows application, you only need to include the
Microsoft.Identity.Client package. The rest of the broker-related code is exactly the same as in the .NET 6.0 snippet above.
Universal Windows Platform
No changes are required for UWP applications. Because the platform does not support the updated broker, existing applications should continue using
MAUI and Xamarin
For both MAUI and Xamarin, developers will need to use the
RuntimeBroker class. When calling
AcquireTokenInteractive, a parent window handle will now be required.
return await PCA.AcquireTokenInteractive(scopes) .WithParentActivityOrWindow(PlatformConfig.Instance.ParentWindow) .ExecuteAsync() .ConfigureAwait(false);
Upgrading From Preview Releases
If you have previously used a preview release of MSAL, keep in mind that the
WithBrokerPreview API is now deprecated. The stable API is now exposed through
WithBroker(BrokerOptions) and you should update your code accordingly.
Upgrading Older Applications
The biggest change around the new broker for existing applications is related to the
WithWindowsBroker API call – it will now require a parent window handle. When invoked, it will automatically rely on the new broker experience. There are many ways to obtain a window handle depending on the application. We recommend checking out the Retrieve a window handle (HWND) for more details.
Additionally, we’ve added
WithWindowsDesktopFeatures to support legacy applications and marked
WithDesktopFeatures API as obsolete.
Addressing Multiple Frameworks
If you have multiple target frameworks in your project, relevant MSAL packages can be imported as follows:
<ItemGroup> <PackageReference Include="Microsoft.Identity.Client" Version="4.52.0" /> </ItemGroup> <ItemGroup Condition="'$(TargetFramework)' == 'net48'"> <PackageReference Include="Microsoft.Identity.Client.Desktop" Version="4.52.0" /> <Reference Include="System.Windows.Forms" /> </ItemGroup> <ItemGroup Condition="$(TargetFramework) == 'net6.0' "> <PackageReference Include="Microsoft.Identity.Client.Broker" Version="4.52.0" /> </ItemGroup>
If you’re ready to dive in, a reference project for the new broker can be found in the library source code repository on GitHub. This sample shows how to get started along with the many different variations in ways in which the Windows broker can be used to authenticate a user.
We would like to extend a huge thank you to our partners and community for helping shape the new broker API. As the library evolves, we would love to hear more from you on how we can improve the developer experience and our feature set – open a new issue for any feedback and we will address it as soon as possible.