Dela via


Skrivbordsapp som anropar webb-API:er: Hämta en token med hjälp av WAM

Microsoft Authentication Library (MSAL) anropar Web Account Manager (WAM), en Windows 10+-komponent som fungerar som autentiseringskoordinator. Med asynkron meddelandekö kan användare av din app dra nytta av integrering med konton som är kända för Windows, till exempel det konto som du loggade in på Windows-sessionen.

WAM-värdeförslag

Att använda en autentiseringskoordinator, till exempel WAM, har många fördelar:

  • Förbättrad säkerhet. Se Tokenskydd.
  • Stöd för Windows Hello, villkorlig åtkomst och FIDO-nycklar.
  • Integrering med vyn e-post och konton i Windows.
  • Snabb enkel inloggning.
  • Möjlighet att logga in tyst med det aktuella Windows-kontot.
  • Felkorrigeringar och förbättringar som levereras med Windows.

WAM-begränsningar

  • WAM är tillgängligt på Windows 10 och senare, och på Windows Server 2019 och senare. I Mac, Linux och tidigare versioner av Windows återgår MSAL automatiskt till en webbläsare.
  • Azure Active Directory B2C -myndigheter (Azure AD B2C) och Active Directory Federation Services (AD FS) (AD FS) stöds inte. MSAL återgår till en webbläsare.

WAM-integreringspaket

De flesta appar måste referera till paketet för att använda den här integreringen Microsoft.Identity.Client.Broker . .NET MAUI-appar behöver inte göra detta eftersom funktionerna finns i MSAL när målet är net6-windows och senare.

WAM-anropsmönster

Du kan använda följande mönster för WAM:

    // 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                                  
    }

Om en asynkron meddelandekö inte finns (till exempel Windows 8.1, Mac eller Linux) återgår MSAL till en webbläsare där omdirigerings-URI-regler gäller.

Omdirigerings-URI

Du behöver inte konfigurera WAM-omdirigerings-URI:er i MSAL, men du behöver konfigurera dem i appregistreringen:

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

Cachepersistence för token

Det är viktigt att bevara MSAL-tokencacheminnet eftersom MSAL fortsätter att lagra ID-token och kontometadata där. Mer information finns i Token cache serialisering i MSAL.NET.

Konto för tyst inloggning

För att hitta ett konto för tyst inloggning rekommenderar vi det här mönstret:

  • Om användaren har loggat in tidigare använder du det kontot. Om inte använder du PublicClientApplication.OperatingSystemAccount för det aktuella Windows-kontot.
  • Tillåt att användaren ändrar till ett annat konto genom att logga in interaktivt.

Överordnade fönsterhandtag

Du måste konfigurera MSAL med det fönster som den interaktiva upplevelsen ska vara överordnad till med hjälp WithParentActivityOrWindow av API:er.

Användargränssnittsprogram

Användargränssnittsappar som Windows Forms (WinForms), Windows Presentation Foundation (WPF) eller Windows UI Library version 3 (WinUI3) finns i Hämta ett fönsterhandtag.

Konsolprogram

För konsolprogram är konfigurationen mer involverad på grund av terminalfönstret och dess flikar. Använd följande kod:

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;
}

Felsökning

Felmeddelandet "WAM-kontoväljaren returnerade inte något konto"

Meddelandet "WAM-kontoväljaren returnerade inte ett konto" anger att programanvändaren antingen stängde dialogrutan som visar konton eller att själva dialogrutan kraschade. En krasch kan inträffa om AccountsControl, en Windows-kontroll, har registrerats felaktigt i Windows. Så här löser du problemet:

  1. I aktivitetsfältet högerklickar du på Start och väljer sedan Windows PowerShell (admin).

  2. Om du uppmanas av en dialogruta för användarkontokontroll väljer du Ja för att starta PowerShell.

  3. Kopiera och kör sedan följande skript:

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

Felmeddelandet "MsalClientException: ErrorCode: wam_runtime_init_failed" under en enda fildistribution

Du kan se följande fel när du paketerar programmet i ett enda filpaket:

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

Det här felet anger att de interna binärfilerna från Microsoft.Identity.Client.NativeInterop inte paketerades i det enskilda filpaketet. Om du vill bädda in filerna för extrahering och hämta en utdatafil anger du egenskapen IncludeNativeLibrariesForSelfExtract till true. Läs mer om hur du paketera interna binärfiler i en enda fil.

Anslutningsproblem

Om programanvändaren regelbundet ser ett felmeddelande som liknar "Kontrollera anslutningen och försök igen" läser du felsökningsguiden för Office. Den felsökningsguiden använder även asynkron meddelandekö.

Exempel

Du hittar ett WPF-exempel som använder WAM på GitHub.

Nästa steg

Gå vidare till nästa artikel i det här scenariot, Anropa ett webb-API från skrivbordsappen.