Partilhar via


Aplicativo de área de trabalho que chama APIs da Web: adquira um token usando o WAM

A Microsoft Authentication Library (MSAL) chama o Web Account Manager (WAM), um componente do Windows 10+ que atua como um agente de autenticação. O agente permite que os usuários do seu aplicativo se beneficiem da integração com contas conhecidas do Windows, como a conta que você entrou na sessão do Windows.

Proposta de valor da WAM

Usar um agente de autenticação como o WAM tem vários benefícios:

  • Segurança reforçada. Consulte Proteção de tokens.
  • Suporte para chaves Windows Hello, Acesso Condicional e FIDO.
  • Integração com a vista Windows Email & accounts .
  • Início de sessão único rápido.
  • Capacidade de entrar silenciosamente com a conta atual do Windows.
  • Correções de bugs e melhorias fornecidas com o Windows.

Limitações do WAM

  • O WAM está disponível no Windows 10 e posterior, e no Windows Server 2019 e posterior. No Mac, Linux e versões anteriores do Windows, o MSAL retorna automaticamente a um navegador.
  • Não há suporte para as autoridades do Azure Ative Directory B2C (Azure AD B2C) e dos Serviços de Federação do Ative Directory (AD FS). O MSAL recorre a um navegador.

Pacote de integração WAM

A maioria dos aplicativos precisa fazer referência ao Microsoft.Identity.Client.Broker pacote para usar essa integração. Os aplicativos .NET MAUI não precisam fazer isso, porque a funcionalidade está dentro do MSAL quando o destino está net6-windows e posteriormente.

Padrão de chamada WAM

Você pode usar o seguinte padrão para 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                                  
    }

Se um broker não estiver presente (por exemplo, Windows 8.1, Mac ou Linux), o MSAL retornará a um navegador, onde as regras de URI de redirecionamento se aplicam.

Redirecionar URL

Você não precisa configurar URIs de redirecionamento WAM no MSAL, mas precisa configurá-los no registro do aplicativo:

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

Persistência de cache de token

É importante persistir o cache de tokens MSAL porque o MSAL continua a armazenar tokens de ID e metadados de conta lá. Para obter mais informações, consulte Serialização de cache de token no MSAL.NET.

Conta para login silencioso

Para encontrar uma conta para login silencioso, recomendamos este padrão:

  • Se o utilizador tiver iniciado sessão anteriormente, utilize essa conta. Caso contrário, use PublicClientApplication.OperatingSystemAccount para a conta atual do Windows.
  • Permita que o usuário mude para uma conta diferente fazendo login interativamente.

Alças da janela pai

Você deve configurar o MSAL com a janela à qual a experiência interativa deve ser parental, usando WithParentActivityOrWindow APIs.

Aplicativos de interface do usuário

Para aplicativos de interface do usuário como Windows Forms (WinForms), Windows Presentation Foundation (WPF) ou Windows UI Library versão 3 (WinUI3), consulte Recuperar um identificador de janela.

Aplicações de consola

Para aplicativos de console, a configuração é mais envolvida por causa da janela do terminal e suas guias. Utilize o seguinte código:

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

Resolução de Problemas

Mensagem de erro "O Seletor de Conta WAM não retornou uma conta"

A mensagem "WAM Account Picker did not return an account" indica que o usuário do aplicativo fechou a caixa de diálogo que exibe contas ou a própria caixa de diálogo travou. Uma falha pode ocorrer se AccountsControl, um controle do Windows, estiver registrado incorretamente no Windows. Para resolver esse problema:

  1. Na barra de tarefas, clique com o botão direito do mouse em Iniciar e selecione Windows PowerShell (Admin).

  2. Se você for solicitado por uma caixa de diálogo Controle de Conta de Usuário, selecione Sim para iniciar o PowerShell.

  3. Copie e execute o seguinte script:

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

Mensagem de erro "MsalClientException: ErrorCode: wam_runtime_init_failed" durante uma implantação de arquivo único

Você pode ver o seguinte erro ao empacotar seu aplicativo em um único pacote de arquivos:

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

Esse erro indica que os binários nativos de Microsoft.Identity.Client.NativeInterop não foram empacotados no pacote de arquivo único. Para incorporar esses arquivos para extração e obter um arquivo de saída, defina a propriedade IncludeNativeLibrariesForSelfExtract como true. Leia mais sobre como empacotar binários nativos em um único arquivo.

Problemas de ligação

Se o utilizador da aplicação vir regularmente uma mensagem de erro semelhante a "Verifique a sua ligação e tente novamente", consulte o guia de resolução de problemas do Office. Esse guia de solução de problemas também usa o corretor.

Exemplo

Você pode encontrar um exemplo de WPF que usa WAM no GitHub.

Próximos passos

Passe para o próximo artigo neste cenário, Chamar uma API da Web a partir do aplicativo da área de trabalho.