Skip to content
Bogdan Gavril edited this page Aug 23, 2022 · 128 revisions

MSAL is able to call Web Account Manager, a Windows 10 component that ships with the OS. This component acts as an authentication broker and users of your app benefit from integration with accounts known from Windows, such as the account you signed-in with in your Windows session.

New WAM Preview in MSAL 4.44+

The New MSAL WAM Preview is an abstraction layer based on MSAL C++ which fixes a number of issues with the existing WAM implementation. New applications should use this implementation.

  • assembly size issues
  • run-as-admin issues
  • adds support for POP tokens

To enable WAM preview

  • add a reference to Microsoft.Identity.Client.Broker (and you can remove any reference to Microsoft.Identity.Client.Desktop)
  • instead of .WithBroker(), call .WithBrokerPreview().

Note: The old WAM experience is documented at: https://docs.microsoft.com/en-us/azure/active-directory/develop/scenario-desktop-acquire-token-wam and showcases details about redirect URI, fallback experience on older Windows, Mac and Linux etc.

var pca = PublicClientApplicationBuilder
              .Create("1234...")
              .WithAuthority("https://login.microsoftonline.com/common")
              .WithBrokerPreview(true)   // this method exists in Microsoft.Identity.Client.Broker package
              .Build();

Parent Window Handles

It is now mandatory to tell MSAL the window the interactive experience should be parented to, using WithParentWindowOrActivity APIs. Trying to infer a window is not feasible and in the past, this has led to bad user experience where the auth window is hidden behind the application.

// In a WinForms app, in a Form
IntPtr windowHandle = this.Handle;

// In a WPF app 
IntPtr windowHandle = new System.Windows.Interop.WindowInteropHelper(this).Handle;

For console applications it is a bit more involved, because of the terminal window and its tabs.

enum GetAncestorFlags
{   
    GetParent = 1,
    GetRoot = 2,
    /// <summary>
    /// Retrieves the owned root window by walking the chain of parent and owner windows returned by GetParent.
    /// </summary>
    GetRootOwner = 3
}

/// <summary>
/// Retrieves the handle to the ancestor of the specified window.
/// </summary>
/// <param name="hwnd">A handle to the window whose ancestor is to be retrieved.
/// If this parameter is the desktop window, the function returns NULL. </param>
/// <param name="flags">The ancestor to be retrieved.</param>
/// <returns>The return value is the handle to the ancestor window.</returns>
[DllImport("user32.dll", ExactSpelling = true)]
static extern IntPtr GetAncestor(IntPtr hwnd, GetAncestorFlags flags);

[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();

public IntPtr GetConsoleOrTerminalWindow()
{
   IntPtr consoleHandle = GetConsoleWindow();
   IntPtr handle = GetAncestor(consoleHandle, GetAncestorFlags.GetRootOwner );
  
   return handle;
}

The logic below will eventually be added as a helper in MSAL, tracking work item 3590. For now, copy this into your app.

Proof of Possession Access Tokens

MSAL already supports PoP tokens in confidential client flows starting MSAL 4.8+, With the new MSAL WAM Broker you can acquire PoP tokens for public client flows as well.

Bearer tokens are the norm in modern identity flows, however they are vulnerable to being stolen and used to access a protected resource.

Proof of Possession (PoP) tokens mitigate this threat via 2 mechanisms:

  • they are bound to the user / machine that wants to access a protected resource, via a public / private key pair
  • they are bound to the protected resource itself, i.e. a token that is used to access GET https://contoso.com/transactions cannot be used to access GET https://contoso.com/tranfer/100

In order to utilize the new broker to perform POP, see the code snippet here.

For more details, see RFC 7800

WAM value proposition

Using an authentication broker such as WAM has numerous benefits.

  • Enhanced security (your app does not have to manage the powerful refresh token)
  • Better support for Windows Hello, Conditional Access and FIDO keys
  • Integration with Windows' "Email and Accounts" view
  • Better Single Sign-On (users don't have to reenter passwords)
  • Most bug fixes and enhancements will be shipped with Windows

WAM limitations

  • B2C and ADFS authorities are not supported. MSAL will fallback to a browser.
  • Available on Win10+ and Win Server 2019+. On Mac, Linux and earlier Windows MSAL will fallback to a browser.
  • Not available on Xbox.

Redirect URI

WAM redirect URIs do not need to be configured in MSAL, but they must be configured in the app registration.

Win32 (.NET framework / .NET 5)

ms-appx-web://microsoft.aad.brokerplugin/{client_id}

GetAccounts

GetAccounts returns accounts of users who have previously logged in interactively into the app.

WAM can also list the OS-wide Work and School accounts which will be made available in the new broker soon.

RemoveAsync

  • Removes all account information from MSAL's token cache (this includes MSA - i.e. personal accounts - account info and other account information copied by MSAL into its cache).
  • Removes app-only (not OS-wide) accounts.

Note: Apps cannot remove OS accounts. Only users can do that.

Getting started with MSAL.NET

Acquiring tokens

Desktop/Mobile apps

Web Apps / Web APIs / daemon apps

Advanced topics

News

FAQ

Other resources

Clone this wiki locally