Классическое приложение, которое вызывает веб-API: получение маркера с помощью WAM

Библиотека проверки подлинности Майкрософт (MSAL) вызывает диспетчер веб-учетных записей (WAM), компонент Windows 10+, который выступает в качестве брокера проверки подлинности. Брокер позволяет пользователям приложения воспользоваться интеграцией с учетными записями Windows, такими как учетная запись, вошедшего в сеанс Windows.

Предлагаемые преимущества WAM

Использование брокера проверки подлинности, например WAM, имеет множество преимуществ:

  • Улучшенная безопасность. См. раздел "Защита маркеров".
  • Поддержка ключей Windows Hello, условного доступа и FIDO.
  • Интеграция с представлением электронной почты и учетных записей Windows.
  • Быстрый единый вход.
  • Возможность автоматического входа с помощью текущей учетной записи Windows.
  • Исправления ошибок и улучшения, отправленные в Windows.

Ограничения WAM

  • WAM доступен в Windows 10 и более поздних версиях, а также в Windows Server 2019 и более поздних версий. В Mac, Linux и более ранних версиях Windows MSAL автоматически возвращается в браузер.
  • Azure Active Directory B2C (Azure AD B2C) и службы федерации Active Directory (AD FS) (AD FS) не поддерживаются. MSAL возвращается в браузер.

Пакет интеграции WAM

Большинство приложений должны ссылаться на Microsoft.Identity.Client.Broker пакет для использования этой интеграции. Приложения .NET MAUI не должны делать это, так как функциональность находится внутри MSAL, когда целевой объект и net6-windows более поздние версии.

Схема вызова WAM

Для 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-адрес перенаправления

Вам не нужно настраивать 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 не вернуло учетную запись"

Сообщение "Средство выбора учетных записей WAM не вернуло учетную запись" указывает, что пользователь приложения закрыл диалоговое окно, отображающее учетные записи, или само диалоговое окно завершилось сбоем. Сбой может произойти, если AccountsControlэлемент управления Windows зарегистрирован неправильно в Windows. Для решения этой проблемы сделайте следующее:

  1. На панели задач щелкните правой кнопкой мыши пуск и выберите Windows PowerShell (администратор).

  2. Если появится диалоговое окно "Контроль учетных записей пользователей", нажмите кнопку "Да ", чтобы запустить PowerShell.

  3. Скопируйте и выполните следующий сценарий:

    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 из классического приложения.