Compartilhar via


Aplicativo da área de trabalho que chama as APIs Web: adquirir um token interativamente

O exemplo a seguir mostra o código mínimo para se obter um token de modo interativo para ler o perfil do usuário com Microsoft Graph.

Código em MSAL.NET

string[] scopes = new string[] { "user.read" };

var app = PublicClientApplicationBuilder.Create("YOUR_CLIENT_ID")
    .WithDefaultRedirectUri()
    .Build();

var accounts = await app.GetAccountsAsync();

AuthenticationResult result;
try
{
    result = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault())
      .ExecuteAsync();
}
catch (MsalUiRequiredException)
{
    result = await app.AcquireTokenInteractive(scopes).ExecuteAsync();
}

Parâmetros obrigatórios

AcquireTokenInteractive tem um parâmetro obrigatório, scopes. Ele contpem uma enumeração de cadeias de caracteres que definem os escopos para os quais um token é necessário. Se o token for para o Microsoft Graph, os escopos necessários poderão ser encontrados na referência de API de cada API do Microsoft Graph na seção chamada "Permissões". Por exemplo, para listar os contatos do usuário, você deve usar User.Read e Contacts.Read como escopo. Para obter mais informações, confira Referência de permissões do Microsoft Graph.

Na área de trabalho e nos aplicativos móveis, é importante especificar o pai usando .WithParentActivityOrWindow. Em muitos casos, é um requisito e a MSAL gerará exceções.

Para aplicativos da área de trabalho, consulte Identificadores de janela pai.

Para aplicativos móveis, forneça Activity (Android) ou UIViewController (iOS).

Parâmetros opcionais específicos no MSAL.NET

WithParentActivityOrWindow

A interface do usuário é importante por ser interativa. AcquireTokenInteractive tem um parâmetro opcional específico que pode especificar, para plataformas que têm suporte para ele, a interface do usuário pai. Quando usado em um aplicativo de área de trabalho, .WithParentActivityOrWindow tem um tipo diferente, que depende da plataforma.

Como alternativa, você pode omitir o parâmetro de janela pai opcional para criar uma janela, se não quiser controlar onde a caixa de diálogo de entrada aparece na tela. Essa opção é aplicável a aplicativos baseados em uma linha de comando, são usados para passar chamadas para qualquer outro serviço de back-end e não precisam de janelas para interação do usuário.

// net45
WithParentActivityOrWindow(IntPtr windowPtr)
WithParentActivityOrWindow(IWin32Window window)

// Mac
WithParentActivityOrWindow(NSWindow window)

// .NET Standard (this will be on all platforms at runtime, but only on .NET Standard platforms at build time)
WithParentActivityOrWindow(object parent).

Comentários:

  • No .NET Standard, o valor object esperado é Activity, no Android, UIViewController, no iOS, NSWindow, no MacIWin32Window ou IntPr no Windows.

  • No Windows, você deve chamar AcquireTokenInteractive do thread da interface do usuário para que o navegador inserido obtenha o contexto apropriado de sincronização da interface do usuário. Não chamar a partir do thread da interface do usuário pode fazer com que as mensagens não sejam bombeadas corretamente, além de levar a cenários de deadlock com a interface do usuário. Uma maneira de chamar as Bibliotecas de autenticação da Microsoft (MSAL) a partir do thread da interface do usuário caso você já não esteja no thread da interface do usuário é usar o Dispatcher no Windows Presentation Foundation (WPF).

  • Caso esteja usando o WPF para obter uma janela de um controle do WPF, você poderá usar a classe WindowInteropHelper.Handle. Então, a chamada é de um controle do WPF (this):

    result = await app.AcquireTokenInteractive(scopes)
                      .WithParentActivityOrWindow(new WindowInteropHelper(this).Handle)
                      .ExecuteAsync();
    

WithPrompt

WithPrompt() é usado para controlar a interatividade com o usuário por meio da especificação de um prompt. O comportamento exato pode ser controlado usando a estrutura Microsoft.Identity.Client.Prompt.

A estrutura define as constantes a seguir:

  • SelectAccount força o serviço de token de segurança (STS) a apresentar a caixa de diálogo da seleção de conta que contém contas para as quais o usuário tem uma sessão. Essa é a opção padrão. É útil quando você quer permitir que os usuários escolham entre diferentes identidades.

    Essa opção faz com que a MSAL envie prompt=select_account para o provedor de identidade. Ele fornece a melhor experiência possível com base nas informações disponíveis, como a conta e a presença de uma sessão para o usuário. Não altere isso a menos que você tenha uma boa razão.

  • Consent permite que o desenvolvedor do aplicativo force usuário a dar seu consentimento, mesmo que ele já tenha sido concedido antes. Nesse caso, a MSAL envia prompt=consent para o provedor de identidade. Você pode usar essa opção em alguns aplicativos focados em segurança em que a governança da organização exige que a caixa de diálogo de consentimento seja exibida sempre que o usuário abrir o aplicativo.

  • ForceLogin permite que o desenvolvedor do aplicativo solicite que o usuário forneça credenciais, mesmo que essa solicitação possa não ser necessária. Essa opção pode ser útil para permitir que o usuário entre novamente caso a aquisição de um token falhe. Nesse caso, a MSAL envia prompt=login para o provedor de identidade. Às vezes, as organizações usam essa opção em aplicativos focados em segurança, em que a governança exige que os usuários entrem sempre que acessam partes específicas de um aplicativo.

  • Create dispara uma experiência de inscrição para identidades externas através do envio de prompt=create ao provedor de identidade. Os aplicativos do Azure Active Directory B2C (Azure AD B2C) não devem enviar essa solicitação. Para obter mais informações, confira Adicionar um fluxo de usuário de inscrição para autoatendimento a um aplicativo.

  • Never(somente para .NET 4.5 e Windows Runtime) não solicita ao usuário. Em vez disso, ele tenta usar o cookie armazenado no mondo de exibição da Web incorporada oculta.

    O uso dessa opção pode falhar. Nesse caso, AcquireTokenInteractive gera uma exceção para notificar que uma interação da interface do usuário seja necessária. Em seguida, use outro parâmetro Prompt.

  • NoPrompt não enviará nenhuma solicitação para o provedor de identidade. O provedor de identidade decide qual experiência de entrada é melhor para o usuário (logon único ou conta de seleção).

    Essa opção é obrigatória para editar políticas de perfil no Azure AD B2C. Para obter mais informações, consulte Especificações do Azure AD B2C.

WithUseEmbeddedWebView

Esse método permite que você especifique se deseja forçar o uso de um modo de exibição da Web incorporado ou de um modo de exibição da Web do sistema (quando disponível). Para obter mais informações, consulte Uso de navegadores da Web.

var result = await app.AcquireTokenInteractive(scopes)
                    .WithUseEmbeddedWebView(true)
                    .ExecuteAsync();

WithExtraScopeToConsent

Esse modificador é para cenários avançados em que você deseja que o usuário consenta com vários recursos antecipadamente e não deseja usar o consentimento incremental. Os desenvolvedores normalmente usam o consentimento incremental com MSAL.NET e o plataforma de identidade da Microsoft.

var result = await app.AcquireTokenInteractive(scopesForCustomerApi)
                     .WithExtraScopeToConsent(scopesForVendorApi)
                     .ExecuteAsync();

WithCustomWebUi

Uma interface do usuário da Web é um mecanismo usado para invocar um navegador. Esse mecanismo pode ser um controle WebBrowser da interface do usuário dedicada ou uma maneira de delegar a abertura do navegador. A MSAL fornece implementações da interface do usuário da Web para a maioria das plataformas, mas você pode desejar hospedar o navegador por conta própria nesses casos:

  • Você tem plataformas que a MSAL não abrange explicitamente, como Blazor, Unity e Mono em áreas de trabalho.
  • Você deseja testar o aplicativo na interface do usuário e usar um navegador automatizado que possa ser usado com Selenium.
  • O navegador e o aplicativo que executa a MSAL estão em processos separados.

Para fazer isso, você fornece start Url à MSAL, que precisa ser exibido em um navegador da sua escolha para que o usuário final possa inserir itens como o nome de usuário. Após a conclusão da autenticação, seu aplicativo precisará transmitir end Url novamente para a MSAL, que contém um código fornecido pela ID do Microsoft Entra. O host de end Url é sempre redirectUri. Para interceptar o end Url, siga um destes procedimentos:

  • Monitore os redirecionamentos de navegador até chegar ao redirect Url.
  • Faça com que o navegador redirecione para uma URL monitorada por você.

WithCustomWebUi é um ponto de extensibilidade que pode ser usado para você fornecer sua própria interface do usuário em aplicativos cliente públicos. Você também pode permitir que o usuário passe pelo ponto de extremidade /Authorize do provedor de identidade e permitir que eles entrem e consintam. Com isso, o MSAL.NET pode resgatar o código de autenticação e obter um token.

Por exemplo, você pode usar WithCustomWebUi no Visual Studio para que os aplicativos do Electron (por exemplo, comentários do Visual Studio) forneçam a interação com a Web, mas deixe que o MSAL.NET faça a maior parte do trabalho. Você também pode usar WithCustomWebUi caso deseje fornecer a automação da interface do usuário.

Em aplicativos cliente públicos, o MSAL.NET usa a PKCE (Chave de Prova para Troca de Código) padrão para garantir que a segurança seja respeitada. Somente o MSAL.NET pode resgatar o código. Para obter mais informações, consulte RFC 7636 – Chave de Prova para Troca de Código por clientes públicos do OAuth.

using Microsoft.Identity.Client.Extensions;
Usar o WithCustomWebUI

Para usar o WithCustomWebUI, siga as etapas a seguir:

  1. Implemente a interface ICustomWebUi. Para saber mais, confira essa página do GitHub.

  2. Implemente um método AcquireAuthorizationCodeAsync e aceite a URL do código de autorização calculada por MSAL.NET.

  3. Depois, permita que o usuário percorra a interação com o provedor de identidade e retorne a URL pela qual o provedor de identidade teria chamado sua implementação novamente junto com o código de autorização. Caso tenha problemas, sua implementação deverá gerar uma exceção MsalExtensionException para uma boa cooperação com a MSAL.

  4. Na chamada de AcquireTokenInteractive, use o modificador .WithCustomUI() passando a instância da interface do usuário da Web personalizada:

    result = await app.AcquireTokenInteractive(scopes)
                      .WithCustomWebUi(yourCustomWebUI)
                      .ExecuteAsync();
    

A equipe do MSAL.NET reescreveu os testes da interface do usuário para usar esse mecanismo de extensibilidade. Caso tenha interesse, examine a classe SeleniumWebUI no código-fonte MSAL.NET.

Ofereça uma ótima experiência com o SystemWebViewOptions

No MSAL.NET 4.1 SystemWebViewOptions, você pode especificar:

  • O URI a ser acessado (BrowserRedirectError) ou o fragmento HTML a ser exibido (HtmlMessageError) em caso de erros de entrada ou de consentimento no navegador da Web do sistema.
  • O URI a ser acessado (BrowserRedirectSuccess) ou o fragmento HTML a ser exibido (HtmlMessageSuccess) em caso de entrada ou de consentimento bem-sucedidos.
  • A ação a ser executada para iniciar o navegador do sistema. Você pode fornecer sua própria implementação por meio da definição do delegado OpenBrowserAsync. A classe também fornece uma implementação padrão para dois navegadores: OpenWithEdgeBrowserAsync para o Microsoft Edge e OpenWithChromeEdgeBrowserAsync para o Microsoft Edge no Chromium.

Para usar essa estrutura, escreva algo semelhante ao exemplo a seguir:

IPublicClientApplication app;
...

options = new SystemWebViewOptions
{
 HtmlMessageError = "<b>Sign-in failed. You can close this tab ...</b>",
 BrowserRedirectSuccess = "https://contoso.com/help-for-my-awesome-commandline-tool.html"
};

var result = app.AcquireTokenInteractive(scopes)
                .WithEmbeddedWebView(false)       // The default in .NET
                .WithSystemWebViewOptions(options)
                .Build();

Outros parâmetros opcionais

Para saber mais sobre todos os outros parâmetros opcionais de AcquireTokenInteractive, consulte AcquireTokenInteractiveParameterBuilder.

Próximas etapas