Классическое приложение, которое вызывает веб-API: получение маркера с помощью WAM
Библиотека проверки подлинности Майкрософт (MSAL) вызывает диспетчер веб-учетных записей (WAM), компонент Windows 10+, который выступает в качестве брокера проверки подлинности. Брокер позволяет пользователям приложения воспользоваться интеграцией с учетными записями Windows, такими как учетная запись, вошедшего в сеанс Windows.
Использование брокера проверки подлинности, например WAM, имеет множество преимуществ:
- Улучшенная безопасность. См. раздел "Защита маркеров".
- Поддержка ключей Windows Hello, условного доступа и FIDO.
- Интеграция с представлением электронной почты и учетных записей Windows.
- Быстрый единый вход.
- Возможность автоматического входа с помощью текущей учетной записи Windows.
- Исправления ошибок и улучшения, отправленные в Windows.
- WAM доступен в Windows 10 и более поздних версиях, а также в Windows Server 2019 и более поздних версий. В Mac, Linux и более ранних версиях Windows MSAL автоматически возвращается в браузер.
- Azure Active Directory B2C (Azure AD B2C) и службы федерации Active Directory (AD FS) (AD FS) не поддерживаются. MSAL возвращается в браузер.
Большинство приложений должны ссылаться на Microsoft.Identity.Client.Broker
пакет для использования этой интеграции. Приложения .NET MAUI не должны делать это, так как функциональность находится внутри MSAL, когда целевой объект и net6-windows
более поздние версии.
Для 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://video2.skills-academy.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
}
Если брокер отсутствует (например, Windows 8.1, Mac или Linux), MSAL возвращается в браузер, где применяются правила URI перенаправления.
Вам не нужно настраивать URI перенаправления WAM в MSAL, но их необходимо настроить в регистрации приложения:
ms-appx-web://microsoft.aad.brokerplugin/{client_id}
Важно сохранить кэш маркеров MSAL, так как MSAL продолжает хранить маркеры идентификаторов и метаданные учетной записи. Дополнительные сведения см. в разделе сериализация кэша маркеров в MSAL.NET.
Чтобы найти учетную запись для автоматического входа, рекомендуется использовать следующий шаблон:
- Если пользователь ранее вошел в систему, используйте ее. Если нет, используйте
PublicClientApplication.OperatingSystemAccount
для текущей учетной записи Windows. - Разрешить пользователю изменять другую учетную запись, войдите в систему в интерактивном режиме.
Необходимо настроить MSAL с окном, в которое должен быть родительский интерактивный интерфейс с помощью WithParentActivityOrWindow
API.
Сведения о приложениях пользовательского интерфейса, таких как Windows Forms (WinForms), Windows Presentation Foundation (WPF) или Библиотеке пользовательского интерфейса Windows версии 3 (WinUI3), см. в разделе "Получение дескриптора окна".
Для консольных приложений конфигурация более вовлечена из-за окна терминала и ее вкладок. Используйте следующий код:
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;
}
Сообщение "Средство выбора учетных записей WAM не вернуло учетную запись" указывает, что пользователь приложения закрыл диалоговое окно, отображающее учетные записи, или само диалоговое окно завершилось сбоем. Сбой может произойти, если AccountsControl
элемент управления Windows зарегистрирован неправильно в Windows. Для решения этой проблемы сделайте следующее:
На панели задач щелкните правой кнопкой мыши пуск и выберите Windows PowerShell (администратор).
Если появится диалоговое окно "Контроль учетных записей пользователей", нажмите кнопку "Да ", чтобы запустить PowerShell.
Скопируйте и выполните следующий сценарий:
if (-not (Get-AppxPackage Microsoft.AccountsControl)) { Add-AppxPackage -Register "$env:windir\SystemApps\Microsoft.AccountsControl_cw5n1h2txyewy\AppxManifest.xml" -DisableDevelopmentMode -ForceApplicationShutdown } Get-AppxPackage Microsoft.AccountsControl
"MsalClientException: ErrorCode: wam_runtime_init_failed" сообщение об ошибке во время развертывания одного файла
При упаковке приложения в один пакет файлов может появиться следующая ошибка:
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
Эта ошибка означает, что собственные двоичные файлы из Microsoft.Identity.Client.NativeInterop не были упакованы в один пакет файлов. Чтобы внедрить эти файлы для извлечения и получить один выходной файл, задайте для свойства IncludeNativeLibrariesForSelfExtract
значение true
. Дополнительные сведения о том, как упаковать собственные двоичные файлы в один файл.
Если пользователь приложения регулярно видит сообщение об ошибке, аналогичное "Проверьте подключение и повторите попытку", ознакомьтесь с руководством по устранению неполадок в Office. Это руководство по устранению неполадок также использует брокер.
Пример WPF, использующий WAM на GitHub.
Перейдите к следующей статье в этом сценарии, Вызов веб-API из классического приложения.