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:
I aktivitetsfältet högerklickar du på Start och väljer sedan Windows PowerShell (admin).
Om du uppmanas av en dialogruta för användarkontokontroll väljer du Ja för att starta PowerShell.
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.