Partilhar via


Executar testes de integração automatizados

Como desenvolvedor, você deseja executar testes de integração automatizados nos aplicativos que desenvolve. Chamar sua API protegida pela plataforma de identidade da Microsoft (ou outras APIs protegidas, como o Microsoft Graph) em testes de integração automatizados é um desafio. O Microsoft Entra ID geralmente requer um prompt de entrada interativo do usuário, que é difícil de automatizar. Este artigo descreve como você pode usar um fluxo não interativo, chamado ROPC (Resource Owner Password Credential Grant), para entrar automaticamente nos usuários para teste.

Para se preparar para seus testes de integração automatizados, crie alguns usuários de teste, crie e configure um registro de aplicativo e, potencialmente, faça algumas alterações de configuração em seu locatário. Algumas dessas etapas exigem privilégios de administrador. Além disso, a Microsoft recomenda que você não use o fluxo ROPC em um ambiente de produção. Crie um locatário de teste separado do qual você seja administrador para que possa executar com segurança e eficácia seus testes de integração automatizados.

Aviso

A Microsoft recomenda que você não use o fluxo ROPC em um ambiente de produção. Na maioria dos cenários de produção, alternativas mais seguras estão disponíveis e são recomendadas. O fluxo ROPC requer um grau muito alto de confiança no aplicativo e acarreta riscos que não estão presentes em outros fluxos de autenticação. Você só deve usar esse fluxo para fins de teste em um locatário de teste separado e somente com usuários de teste.

Importante

  • A plataforma de identidade da Microsoft só suporta ROPC dentro de locatários do Microsoft Entra, não contas pessoais. Isso significa que você deve usar um ponto de extremidade específico do locatário (https://login.microsoftonline.com/{TenantId_or_Name}) ou o ponto de organizations extremidade.
  • As contas pessoais que são convidadas para um inquilino do Microsoft Entra não podem utilizar o ROPC.
  • As contas que não têm senhas não podem entrar com o ROPC, o que significa que recursos como login por SMS, FIDO e o aplicativo Authenticator não funcionarão com esse fluxo.
  • Se os utilizadores precisarem de utilizar a autenticação multifator (MFA) para iniciar sessão na aplicação, serão bloqueados.
  • O ROPC não é suportado em cenários de federação de identidades híbridas (por exemplo, Microsoft Entra ID e Serviços de Federação do Ative Directory (AD FS) usados para autenticar contas locais). Se os utilizadores forem redirecionados para um fornecedor de identidades no local, o Microsoft Entra ID não é capaz de testar o nome de utilizador e a palavra-passe nesse fornecedor de identidades. Contudo, a autenticação pass-through é suportada com o ROPC.
  • Uma exceção a um cenário de federação de identidade híbrida seria a seguinte: a política Home Realm Discovery com AllowCloudPasswordValidation definida como TRUE permitirá que o fluxo ROPC funcione para usuários federados quando a senha local for sincronizada com a nuvem. Para obter mais informações, veja Ativar a autenticação ROPC direta de utilizadores federados para aplicações legadas.

Criar um locatário de teste separado

Usar o fluxo de autenticação ROPC é arriscado em um ambiente de produção, portanto , crie um locatário separado para testar seus aplicativos. Você pode usar um locatário de teste existente, mas precisa ser um administrador no locatário, já que algumas das etapas a seguir exigem privilégios de administrador.

Criar e configurar um cofre de chaves

Recomendamos que você armazene com segurança os nomes de usuário e senhas de teste como segredos no Cofre de Chaves do Azure. Quando você executa os testes posteriormente, os testes são executados no contexto de uma entidade de segurança. A entidade de segurança é um usuário do Microsoft Entra se você estiver executando testes localmente (por exemplo, no Visual Studio ou Visual Studio Code), ou uma entidade de serviço ou identidade gerenciada se estiver executando testes no Azure Pipelines ou em outro recurso do Azure. A entidade de segurança deve ter permissões de Ler e Listar segredos para que o executor de teste possa obter os nomes de usuário e senhas de teste do seu cofre de chaves. Para obter mais informações, leia Autenticação no Cofre da Chave do Azure.

  1. Crie um novo cofre de chaves se ainda não tiver um.
  2. Anote o valor da propriedade URI do Vault (semelhante a https://<your-unique-keyvault-name>.vault.azure.net/) que é usado no teste de exemplo mais adiante neste artigo.
  3. Atribua uma política de acesso para a entidade de segurança que executa os testes. Conceda ao usuário, entidade de serviço ou identidade gerenciada as permissões Obter e Listar segredos no cofre de chaves.

Criar usuários de teste

Gorjeta

As etapas neste artigo podem variar ligeiramente com base no portal a partir do qual você começou.

Crie alguns usuários de teste em seu locatário para teste. Como os usuários de teste não são seres humanos reais, recomendamos que você atribua senhas complexas e armazene essas senhas com segurança como segredos no Cofre de Chaves do Azure.

  1. Entre no centro de administração do Microsoft Entra como pelo menos um administrador de aplicativos na nuvem.
  2. Navegue até Identidade>de usuários Todos os usuários.>
  3. Selecione Novo usuário e crie uma ou mais contas de usuário de teste em seu diretório.
  4. O teste de exemplo mais adiante neste artigo usa um único usuário de teste. Adicione o nome de usuário e a senha de teste como segredos no cofre de chaves que você criou anteriormente. Adicione o nome de usuário como um segredo chamado "TestUserName" e a senha como um segredo chamado "TestPassword".

Criar e configurar um registro de aplicativo

Registre um aplicativo que atua como seu aplicativo cliente ao chamar APIs durante o teste. Esta não deve ser a mesma aplicação que você já pode ter em produção. Você deve ter um aplicativo separado para usar apenas para fins de teste.

Registar uma aplicação

Crie um registro de aplicativo. Você pode seguir as etapas no início rápido de registro do aplicativo. Não é necessário adicionar um URI de redirecionamento ou adicionar credenciais, para que você possa ignorar essas seções.

Anote a ID do aplicativo (cliente), que é usada no teste de exemplo mais adiante neste artigo.

Habilite seu aplicativo para fluxos de clientes públicos

O ROPC é um fluxo de cliente público, portanto, você precisa habilitar seu aplicativo para fluxos de clientes públicos. No registro do seu aplicativo no centro de administração do Microsoft Entra, vá para Configurações avançadas>de autenticação Permitir fluxos de>clientes públicos. Defina a alternância como Sim.

Como o ROPC não é um fluxo interativo, você não será solicitado com uma tela de consentimento para consentir com eles em tempo de execução. Pré-consentimento para as permissões para evitar erros ao adquirir tokens.

Adicione as permissões ao seu aplicativo. Não adicione permissões confidenciais ou de alto privilégio ao aplicativo, recomendamos que você defina o escopo de seus cenários de teste para cenários básicos de integração em torno da integração com o Microsoft Entra ID.

No registro do seu aplicativo no centro de administração do Microsoft Entra, vá para Permissões>da API Adicionar uma permissão. Adicione as permissões necessárias para chamar as APIs que você usará. Um exemplo de teste mais adiante neste artigo usa as https://graph.microsoft.com/User.Read permissões e https://graph.microsoft.com/User.ReadBasic.All .

Depois que as permissões forem adicionadas, você precisará consentir com elas. A maneira como você consente com as permissões depende se seu aplicativo de teste está no mesmo locatário que o registro do aplicativo e se você é um administrador no locatário.

O registo da aplicação e da aplicação está no mesmo inquilino e você é um administrador

Se planeia testar a sua aplicação no mesmo inquilino em que a registou e é administrador nesse inquilino, pode consentir as permissões do centro de administração do Microsoft Entra. No registro do seu aplicativo no portal do Azure, vá para Permissões de API e selecione o botão Conceder consentimento de administrador para your_tenant_name> ao lado do botão Adicionar uma permissão e, em seguida, Sim para <confirmar.

O registro de aplicativos e aplicativos está em locatários diferentes ou você não é um administrador

Se você não planeja testar seu aplicativo no mesmo locatário em que o registrou ou não é um administrador em seu locatário, não poderá consentir com as permissões do centro de administração do Microsoft Entra. No entanto, você ainda pode consentir com algumas permissões acionando um prompt de entrada em um navegador da Web.

No registro do seu aplicativo no centro de administração do Microsoft Entra, vá para Configurações da plataforma de>autenticação>Adicionar uma plataforma>Web. Adicione o URI de redirecionamento "https://localhost" e selecione Configurar.

Não há como os usuários não administradores consentirem previamente por meio do portal do Azure, portanto, envie a seguinte solicitação em um navegador. Quando lhe for pedido o ecrã de início de sessão, inicie sessão com uma conta de teste que criou num passo anterior. Consentimento para as permissões solicitadas. Talvez seja necessário repetir esta etapa para cada API que você deseja chamar e testar o usuário que deseja usar.

// Line breaks for legibility only

https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id={your_client_ID}
&response_type=code
&redirect_uri=https://localhost
&response_mode=query
&scope={resource_you_want_to_call}/.default
&state=12345

Substitua {tenant} pelo ID do locatário, {your_client_ID} pelo ID do cliente do seu aplicativo e {resource_you_want_to_call} pelo URI do identificador (por exemplo, ";)https://graph.microsoft.com" ou ID do aplicativo da API que você está tentando acessar.

Excluir aplicativos e usuários de teste da sua política de MFA

Seu locatário provavelmente tem uma política de Acesso Condicional que requer autenticação multifator (MFA) para todos os usuários, conforme recomendado pela Microsoft. O MFA não funcionará com o ROPC, portanto, você precisará isentar seus aplicativos de teste e usuários de teste desse requisito.

Para excluir contas de usuário:

  1. Entre no centro de administração do Microsoft Entra como pelo menos um administrador de aplicativos na nuvem.
  2. Navegue até Central de Segurança de Identidade>no painel de navegação esquerdo e selecione Acesso Condicional.
  3. Em Políticas, selecione a política de Acesso Condicional que requer MFA.
  4. Selecione Usuários ou identidades de carga de trabalho.
  5. Marque a guia Excluir e, em seguida, a caixa de seleção Usuários e grupos.
  6. Selecione a(s) conta(s) de usuário a ser excluída(s) em Selecionar usuários excluídos.
  7. Selecione o botão Selecionar e, em seguida, Guarde.

Para excluir um aplicativo de teste:

  1. Em Políticas, selecione a política de Acesso Condicional que requer MFA.
  2. Selecione Aplicações na cloud ou ações.
  3. Selecione o separador Excluir e, em seguida, selecione aplicações na nuvem excluídas.
  4. Selecione o(s) aplicativo(s) que deseja excluir em Selecionar aplicativos de nuvem excluídos.
  5. Selecione o botão Selecionar e, em seguida, Guarde.

Escreva seus testes de aplicação

Agora que você está configurado, você pode escrever seus testes automatizados. Seguem-se testes para:

  1. O código de exemplo .NET usa a Microsoft Authentication Library (MSAL) e xUnit, uma estrutura de teste comum.
  2. O código de exemplo JavaScript usa a Biblioteca de Autenticação da Microsoft (MSAL) e o Playwright, uma estrutura de teste comum.

Configurar o arquivo appsettings.json

Adicione a ID do cliente do aplicativo de teste que você criou anteriormente, os escopos necessários e o URI do cofre de chaves ao arquivo appsettings.json do seu projeto de teste.

{
  "Authentication": {
    "AzureCloudInstance": "AzurePublic", //Will be different for different Azure clouds, like US Gov
    "AadAuthorityAudience": "AzureAdMultipleOrgs",
    "ClientId": <your_client_ID>
  },

  "WebAPI": {
    "Scopes": [
      //For this Microsoft Graph example.  Your value(s) will be different depending on the API you're calling
      "https://graph.microsoft.com/User.Read",
      //For this Microsoft Graph example.  Your value(s) will be different depending on the API you're calling
      "https://graph.microsoft.com/User.ReadBasic.All"
    ]
  },

  "KeyVault": {
    "KeyVaultUri": "https://<your-unique-keyvault-name>.vault.azure.net//"
  }
}

Configure seu cliente para uso em todas as suas classes de teste

Use SecretClient() para obter os segredos de nome de usuário e senha de teste do Cofre de Chaves do Azure. O código usa back-off exponencial para novas tentativas caso o Cofre da Chave esteja sendo limitado.

DefaultAzureCredential() autentica-se com o Cofre da Chave do Azure obtendo um token de acesso de uma entidade de serviço configurada por variáveis de ambiente ou uma identidade gerenciada (se o código estiver sendo executado em um recurso do Azure com uma identidade gerenciada). Se o código estiver sendo executado localmente, DefaultAzureCredential usará as credenciais do usuário local. Leia mais no conteúdo da biblioteca de cliente do Azure Identity.

Use a Biblioteca de Autenticação da Microsoft (MSAL) para autenticar usando o fluxo ROPC e obter um token de acesso. O token de acesso é passado como um token de portador na solicitação HTTP.

using Xunit;
using System.Threading.Tasks;
using Microsoft.Identity.Client;
using System.Security;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using Microsoft.Extensions.Configuration;
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
using Azure.Core;
using System;

public class ClientFixture : IAsyncLifetime
{
    public HttpClient httpClient;

    public async Task InitializeAsync()
    {
        var builder = new ConfigurationBuilder().AddJsonFile("<path-to-json-file>");

        IConfigurationRoot Configuration = builder.Build();

        var PublicClientApplicationOptions = new PublicClientApplicationOptions();
        Configuration.Bind("Authentication", PublicClientApplicationOptions);
        var app = PublicClientApplicationBuilder.CreateWithApplicationOptions(PublicClientApplicationOptions)
            .Build();

        SecretClientOptions options = new SecretClientOptions()
        {
            Retry =
                {
                    Delay= TimeSpan.FromSeconds(2),
                    MaxDelay = TimeSpan.FromSeconds(16),
                    MaxRetries = 5,
                    Mode = RetryMode.Exponential
                 }
        };

        string keyVaultUri = Configuration.GetValue<string>("KeyVault:KeyVaultUri");
        var client = new SecretClient(new Uri(keyVaultUri), new DefaultAzureCredential(), options);

        KeyVaultSecret userNameSecret = client.GetSecret("TestUserName");
        KeyVaultSecret passwordSecret = client.GetSecret("TestPassword");

        string password = passwordSecret.Value;
        string username = userNameSecret.Value;
        string[] scopes = Configuration.GetSection("WebAPI:Scopes").Get<string[]>();
        SecureString securePassword = new NetworkCredential("", password).SecurePassword;

        AuthenticationResult result = null;
        httpClient = new HttpClient();

        try
        {
            result = await app.AcquireTokenByUsernamePassword(scopes, username, securePassword)
                .ExecuteAsync();
        }
        catch (MsalException) { }

        string accessToken = result.AccessToken;
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
    }

    public Task DisposeAsync() => Task.CompletedTask;
}

Utilização nas suas aulas de teste

O exemplo a seguir é um teste que chama o Microsoft Graph. Substitua esse teste pelo que você gostaria de testar em seu próprio aplicativo ou API.

public class ApiTests : IClassFixture<ClientFixture>
{
    ClientFixture clientFixture;

    public ApiTests(ClientFixture clientFixture)
    {
        this.clientFixture = clientFixture;
    }

    [Fact]
    public async Task GetRequestTest()
    {
        var testClient = clientFixture.httpClient;
        HttpResponseMessage response = await testClient.GetAsync("https://graph.microsoft.com/v1.0/me");
        var responseCode = response.StatusCode.ToString();
        Assert.Equal("OK", responseCode);
    }
}