Desktop-app die web-API's aanroept: een token verkrijgen met behulp van WAM

Microsoft Authentication Library (MSAL) roept Web Account Manager (WAM) aan, een Windows 10+-onderdeel dat fungeert als verificatiebroker. Met de broker kunnen gebruikers van uw app profiteren van integratie met accounts die bekend zijn bij Windows, zoals het account dat u hebt aangemeld bij uw Windows-sessie.

De WAM-waardepropositie

Het gebruik van een verificatiebroker zoals WAM heeft talloze voordelen:

  • Verbeterde beveiliging. Zie Tokenbeveiliging.
  • Ondersteuning voor Windows Hello-, voorwaardelijke toegang en FIDO-sleutels.
  • Integratie met de weergave Windows-e-mail en accounts .
  • Eenmalige aanmelding bij Fast.
  • De mogelijkheid om zich op de achtergrond aan te melden met het huidige Windows-account.
  • Opgeloste fouten en verbeteringen die worden geleverd met Windows.

De WAM-beperkingen

  • WAM is beschikbaar in Windows 10 en hoger en op Windows Server 2019 en hoger. Op Mac, Linux en eerdere versies van Windows wordt MSAL automatisch teruggezet naar een browser.
  • Azure Active Directory B2C (Azure AD B2C) en AD FS-autoriteiten (Active Directory Federation Services) worden niet ondersteund. MSAL valt terug naar een browser.

WAM-integratiepakket

De meeste apps moeten verwijzen naar het Microsoft.Identity.Client.Broker pakket om deze integratie te kunnen gebruiken. .NET MAUI-apps hoeven dit niet te doen, omdat de functionaliteit zich in MSAL bevindt wanneer het doel is net6-windows en later.

Het WAM-aanroeppatroon

U kunt het volgende patroon voor WAM gebruiken:

    // 1. Configuration - read below about redirect URI
    var pca = PublicClientApplicationBuilder.Create("client_id")
                    .WithBroker(new BrokerOptions(BrokerOptions.OperatingSystems.Windows))
                    .Build();

    // Add a token cache; see https://learn.microsoft.com/azure/active-directory/develop/msal-net-token-cache-serialization?tabs=desktop

    // 2. Find an account for silent login

    // Is there an account in the cache?
    IAccount accountToLogin = (await pca.GetAccountsAsync()).FirstOrDefault();
    if (accountToLogin == null)
    {
        // 3. No account in the cache; try to log in with the OS account
        accountToLogin = PublicClientApplication.OperatingSystemAccount;
    }

    try
    {
        // 4. Silent authentication 
        var authResult = await pca.AcquireTokenSilent(new[] { "User.Read" }, accountToLogin)
                                    .ExecuteAsync();
    }
    // Cannot log in silently - most likely Azure AD would show a consent dialog or the user needs to re-enter credentials
    catch (MsalUiRequiredException) 
    {
        // 5. Interactive authentication
        var authResult = await pca.AcquireTokenInteractive(new[] { "User.Read" })
                                    .WithAccount(accountToLogin)
                                    // This is mandatory so that WAM is correctly parented to your app; read on for more guidance
                                    .WithParentActivityOrWindow(myWindowHandle) 
                                    .ExecuteAsync();
                                    
        // Consider allowing the user to re-authenticate with a different account, by calling AcquireTokenInteractive again                                  
    }

Als een broker niet aanwezig is (bijvoorbeeld Windows 8.1, Mac of Linux), valt MSAL terug naar een browser, waar omleidings-URI-regels van toepassing zijn.

Omleidings-URI

U hoeft WAM-omleidings-URI's niet te configureren in MSAL, maar u moet ze wel configureren in de app-registratie:

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

Persistentie van de tokencache

Het is belangrijk om de MSAL-tokencache vast te houden, omdat MSAL daar id-tokens en accountmetagegevens blijft opslaan. Zie Tokencacheserialisatie in MSAL.NET voor meer informatie.

Account voor stille aanmelding

Als u een account wilt vinden voor stille aanmelding, raden we dit patroon aan:

  • Als de gebruiker zich eerder heeft aangemeld, gebruikt u dat account. Als dat niet het is, gebruikt PublicClientApplication.OperatingSystemAccount u dit voor het huidige Windows-account.
  • Hiermee staat u de gebruiker toe om over te schakelen naar een ander account door u interactief aan te melden.

Bovenliggende venstergrepen

U moet MSAL configureren met het venster waaraan de interactieve ervaring moet worden gekoppeld, met behulp van WithParentActivityOrWindow API's.

UI-toepassingen

Zie Een venstergreep ophalen voor UI-apps zoals Windows Forms (WinForms), Windows Presentation Foundation (WPF) of Windows UI Library versie 3 (WinUI3).

Consoletoepassingen

Voor consoletoepassingen is de configuratie meer betrokken vanwege het terminalvenster en de bijbehorende tabbladen. Gebruik de volgende code:

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 will 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();

// This is your window handle!
public IntPtr GetConsoleOrTerminalWindow()
{
   IntPtr consoleHandle = GetConsoleWindow();
   IntPtr handle = GetAncestor(consoleHandle, GetAncestorFlags.GetRootOwner );
  
   return handle;
}

Probleemoplossing

Het foutbericht "WAM-accountkiezer heeft geen account geretourneerd"

Het bericht 'WAM-accountkiezer heeft geen account geretourneerd' geeft aan dat de gebruiker van de toepassing het dialoogvenster met accounts heeft gesloten of dat het dialoogvenster zelf is vastgelopen. Er kan een crash optreden als AccountsControl, een Windows-besturingselement, onjuist is geregistreerd in Windows. U kunt dit probleem als volgt oplossen:

  1. Klik op de taakbalk met de rechtermuisknop op Start en selecteer vervolgens Windows PowerShell (Beheer).

  2. Als u wordt gevraagd door een dialoogvenster Gebruikersaccountbeheer, selecteert u Ja om PowerShell te starten.

  3. Kopieer en voer dan het volgende script uit:

    if (-not (Get-AppxPackage Microsoft.AccountsControl)) { Add-AppxPackage -Register "$env:windir\SystemApps\Microsoft.AccountsControl_cw5n1h2txyewy\AppxManifest.xml" -DisableDevelopmentMode -ForceApplicationShutdown } Get-AppxPackage Microsoft.AccountsControl
    

Foutbericht 'MsalClientException: ErrorCode: wam_runtime_init_failed' tijdens een implementatie van één bestand

Mogelijk ziet u de volgende fout bij het verpakken van uw toepassing in één bestandsbundel:

MsalClientException: wam_runtime_init_failed: The type initializer for 'Microsoft.Identity.Client.NativeInterop.API' threw an exception. See https://aka.ms/msal-net-wam#troubleshooting

Deze fout geeft aan dat de systeemeigen binaire bestanden van Microsoft.Identity.Client.NativeInterop niet zijn verpakt in de bundel met één bestand. Als u deze bestanden wilt insluiten voor extractie en één uitvoerbestand wilt ophalen, stelt u de eigenschap IncludeNativeLibrariesForSelfExtract in op true. Lees meer over het verpakken van systeemeigen binaire bestanden in één bestand.

Verbindingsproblemen

Als de toepassingsgebruiker regelmatig een foutbericht ziet dat lijkt op 'Controleer uw verbinding en probeer het opnieuw', raadpleegt u de gids voor probleemoplossing voor Office. Deze gids voor probleemoplossing maakt ook gebruik van de broker.

Voorbeeld

U vindt een WPF-voorbeeld dat GEBRUIKMAAKT van WAM op GitHub.

Volgende stappen

Ga verder met het volgende artikel in dit scenario, Een web-API aanroepen vanuit de desktop-app.