Exercício – Integrar um plug-in de API com uma API protegida pelo OAuth

Concluído

Os plug-ins de API para Microsoft 365 Copilot permitem-lhe integrar com APIs protegidas pelo OAuth. Mantém o ID de cliente e o segredo da aplicação que protege a sua API de forma segura ao registá-los no cofre do Teams. No runtime, Microsoft 365 Copilot executa o plug-in, obtém as informações do cofre e utiliza-as para obter um token de acesso e chamar a API. Ao seguir este processo, o ID de cliente e o segredo permanecem seguros e nunca são expostos ao cliente.

Abrir o projeto de exemplo

Comece por transferir o projeto de exemplo:

  1. Em um navegador da web, acesse https://aka.ms/learn-da-api-ts-repairs. Recebe um pedido para transferir um ficheiro ZIP com o projeto de exemplo.
  2. Guarde o ficheiro ZIP no seu computador.
  3. Extraia o conteúdo do ficheiro ZIP.
  4. Abra a pasta no Visual Studio Code.

O projeto de exemplo é um projeto do Toolkit de Agentes do Microsoft 365 que inclui um agente declarativo, um plug-in de API e uma API protegida com Microsoft Entra ID. A API está em execução no Azure Functions e implementa a segurança através das capacidades de autenticação e autorização incorporadas do Azure Functions, por vezes referidas como Autenticação Fácil.

Examinar a configuração de autorização OAuth2

Antes de continuar, examine a configuração de autorização OAuth2 no projeto de exemplo.

Examinar a definição da API

Primeiro, veja a configuração de segurança da definição de API incluída no projeto.

Em Visual Studio Code:

  1. Abra o ficheiro appPackage/apiSpecificationFile/repair.yml .

  2. Na secção components.securitySchemes , repare na propriedade oAuth2AuthCode :

    components:
      securitySchemes:
        oAuth2AuthCode:
          type: oauth2
          description: OAuth configuration for the repair service
          flows:
            authorizationCode:
              authorizationUrl: https://login.microsoftonline.com/${{AAD_APP_TENANT_ID}}/oauth2/v2.0/authorize
              tokenUrl: https://login.microsoftonline.com/${{AAD_APP_TENANT_ID}}/oauth2/v2.0/token
              scopes:
                api://${{AAD_APP_CLIENT_ID}}/repairs_read: Read repair records 
    

    A propriedade define um esquema de segurança OAuth2 e inclui informações sobre os URLs a chamar para obter um token de acesso e quais os âmbitos que a API utiliza.

    Importante

    Repare que o âmbito está completamente qualificado com o URI do ID da aplicação (api://...). Ao trabalhar com Microsoft Entra tem de qualificar completamente os âmbitos personalizados. Quando Microsoft Entra vê um âmbito não qualificado, assume que pertence ao Microsoft Graph, o que resulta em erros de fluxo de autorização.

  3. Localize a propriedade paths./repairs.get.security . Tenha em atenção que referencia o âmbito e o esquema de segurança oAuth2AuthCode de que o cliente precisa para efetuar a operação.

    [...]
    paths:
      /repairs:
        get:
          operationId: listRepairs
          [...]
          security:
            - oAuth2AuthCode:
              - api://${{AAD_APP_CLIENT_ID}}/repairs_read
    [...]
    

    Importante

    Listar os âmbitos necessários na especificação da API é puramente informativo. Ao implementar a API, é responsável por validar o token e verificar se contém os âmbitos necessários.

Examinar a implementação da API

Em seguida, veja a implementação da API.

Em Visual Studio Code:

  1. Abra o ficheiro src/functions/repairs.ts .

  2. Na função do processador de reparações , localize a seguinte linha que verifica se o pedido contém um token de acesso com os âmbitos necessários:

    if (!hasRequiredScopes(req, 'repairs_read')) {
      return {
        status: 403,
        body: "Insufficient permissions",
      };
    }
    
  3. A função hasRequiredScopes é implementada ainda mais no ficheiro repairs.ts :

    function hasRequiredScopes(req: HttpRequest, requiredScopes: string[] | string): boolean {
      if (typeof requiredScopes === 'string') {
        requiredScopes = [requiredScopes];
      }
    
      const token = req.headers.get("Authorization")?.split(" ");
      if (!token || token[0] !== "Bearer") {
        return false;
      }
    
      try {
        const decodedToken = jwtDecode<JwtPayload & { scp?: string }>(token[1]);
        const scopes = decodedToken.scp?.split(" ") ?? [];
        return requiredScopes.every(scope => scopes.includes(scope));
      }
      catch (error) {
        return false;
      }
    }
    

    A função começa por extrair o token de portador do cabeçalho do pedido de autorização. Em seguida, utiliza o pacote jwt-decode para descodificar o token e obter a lista de âmbitos da afirmação scp . Por fim, verifica se a afirmação scp contém todos os âmbitos necessários.

    Repare que a função não está a validar o token de acesso. Em vez disso, verifica apenas se o token de acesso contém os âmbitos necessários. Neste modelo, a API está em execução no Azure Functions e implementa a segurança com a Easy Auth, que é responsável por validar o token de acesso. Se o pedido não contiver um token de acesso válido, o Azure Functions runtime rejeita-o antes de atingir o código. Embora a Autenticação Fácil valide o token, não marcar os âmbitos necessários, o que tem de fazer por si próprio.

Examinar a configuração da tarefa do cofre

Neste projeto, vai utilizar o Toolkit de Agentes do Microsoft 365 para adicionar as informações do OAuth ao cofre. O Toolkit de Agentes do Microsoft 365 regista as informações do OAuth no cofre através de uma tarefa especial na configuração do projeto.

Em Visual Studio Code:

  1. Abra o ficheiro ./teampsapp.local.yml .

  2. Na secção de aprovisionamento , localize a tarefa oauth/register .

    - uses: oauth/register
      with:
        name: oAuth2AuthCode
        flow: authorizationCode
        appId: ${{TEAMS_APP_ID}}
        clientId: ${{AAD_APP_CLIENT_ID}}
        clientSecret: ${{SECRET_AAD_APP_CLIENT_SECRET}}
        isPKCEEnabled: true
        # Path to OpenAPI description document
        apiSpecPath: ./appPackage/apiSpecificationFile/repair.yml
      writeToEnvironmentFile:
        configurationId: OAUTH2AUTHCODE_CONFIGURATION_ID
    

    A tarefa utiliza os valores das variáveis de projeto TEAMS_APP_ID, AAD_APP_CLIENT_ID e SECRET_AAD_APP_CLIENT_SECRET , armazenadas nos ficheiros env/.env.local e env/.env.local.user e regista-os no cofre. Também ativa a Chave de Prova para o Code Exchange (PKCE) como uma medida de segurança adicional. Em seguida, utiliza o ID de entrada do cofre e escreve-o no ficheiro de ambiente env/.env.local. O resultado desta tarefa é uma variável de ambiente denominada OAUTH2AUTHCODE_CONFIGURATION_ID. O Toolkit de Agentes do Microsoft 365 escreve o valor desta variável no ficheiro appPackages/ai-plugin.json que contém a definição do plug-in. No runtime, o agente declarativo que carrega o plug-in da API, utiliza este ID para obter as informações de OAuth do cofre e o fluxo de início e autenticação para obter um token de acesso.

    Importante

    A tarefa oauth/register só é responsável por registar as informações do OAuth no cofre se ainda não existir. Se as informações já existirem, o Toolkit de Agentes do Microsoft 365 irá ignorar a execução desta tarefa.

  3. Em seguida, localize a tarefa oauth/update .

    - uses: oauth/update
      with:
        name: oAuth2AuthCode
        appId: ${{TEAMS_APP_ID}}
        apiSpecPath: ./appPackage/apiSpecificationFile/repair.yml
        configurationId: ${{OAUTH2AUTHCODE_CONFIGURATION_ID}}
        isPKCEEnabled: true
    

    A tarefa mantém as informações do OAuth no cofre sincronizadas com o projeto. É necessário que o seu projeto funcione corretamente. Uma das propriedades principais é o URL no qual o plug-in da API está disponível. Sempre que iniciar o seu projeto, o Toolkit de Agentes do Microsoft 365 abre um túnel de programador num novo URL. As informações do OAuth no cofre têm de referenciar este URL para que o Copilot consiga aceder à sua API.

Examinar a configuração de autenticação e autorização

A próxima parte a explorar são as definições de autenticação e autorização do Azure Functions. A API neste exercício utiliza as capacidades de autenticação e autorização incorporadas do Azure Functions. O Toolkit de Agentes do Microsoft 365 configura estas capacidades ao aprovisionar Azure Functions para o Azure.

Em Visual Studio Code:

  1. Abra o ficheiro infra/azure.bicep .

  2. Localize o recurso authSettings :

    resource authSettings 'Microsoft.Web/sites/config@2021-02-01' = {
      parent: functionApp
      name: 'authsettingsV2'
      properties: {
        globalValidation: {
          requireAuthentication: true
          unauthenticatedClientAction: 'Return401'
        }
        identityProviders: {
          azureActiveDirectory: {
            enabled: true
            registration: {
              openIdIssuer: oauthAuthority
              clientId: aadAppClientId
            }
            validation: {
              allowedAudiences: [
                aadAppClientId
                aadApplicationIdUri
              ]
            }
          }
        }
      }
    }
    

    Este recurso permite as capacidades de autenticação e autorização incorporadas na aplicação Azure Functions. Primeiro, na secção globalValidation , define que a aplicação só permite pedidos autenticados. Se a aplicação receber um pedido não autenticado, rejeita-o com um erro 401 HTTP. Em seguida, na secção identityProviders, a configuração define que utiliza Microsoft Entra ID (anteriormente conhecido como Azure Active Directory) para autorizar pedidos. Especifica que Microsoft Entra registo de aplicações utiliza para proteger a API e que audiências podem chamar a API.

Examinar o registo da aplicação Microsoft Entra

A parte final a examinar é a Microsoft Entra registo de aplicação que o projeto utiliza para proteger a API. Ao utilizar o OAuth, protege o acesso aos recursos através de uma aplicação. Normalmente, a aplicação define as credenciais necessárias para obter um token de acesso, como um segredo do cliente ou um certificado. Também especifica as diferentes permissões (também conhecidas como âmbitos) que o cliente pode pedir ao chamar a API. Microsoft Entra registo de aplicações representa uma aplicação na cloud da Microsoft e define uma aplicação para utilização com fluxos de autorização OAuth.

Em Visual Studio Code:

  1. Abra o ficheiro ./aad.manifest.json .

  2. Localize a propriedade oauth2Permissions .

    "oauth2Permissions": [
      {
        "adminConsentDescription": "Allows Copilot to read repair records on your behalf.",
        "adminConsentDisplayName": "Read repairs",
        "id": "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}",
        "isEnabled": true,
        "type": "User",
        "userConsentDescription": "Allows Copilot to read repair records.",
        "userConsentDisplayName": "Read repairs",
        "value": "repairs_read"
      }
    ],
    

    A propriedade define um âmbito personalizado, denominado repairs_read que concede ao cliente a permissão para ler reparações a partir da API de reparações.

  3. Localize a propriedade identifierUris .

    "identifierUris": [
      "api://${{AAD_APP_CLIENT_ID}}"
    ]
    

    A propriedade identifierUris define um identificador que é utilizado para qualificar totalmente o âmbito.

Testar o agente declarativo com o plug-in da API no Microsoft 365 Copilot

O passo final é testar o agente declarativo com o plug-in da API no Microsoft 365 Copilot.

Em Visual Studio Code:

  1. Na Barra de Atividade, ative a extensão Toolkit de Agentes do Microsoft 365 .

  2. No painel de extensão Do Toolkit de Agentes do Microsoft 365 , na secção Contas , certifique-se de que iniciou sessão no seu inquilino do Microsoft 365 com o Copilot ativado.

    Captura de ecrã do Toolkit de Agentes do Microsoft 365 a mostrar o status da ligação ao Microsoft 365.

  3. Na Barra de Atividade, mude para a vista Executar e Depurar .

  4. Na lista de configurações, selecione Depurar no Copilot (Edge) e prima o botão reproduzir para iniciar a depuração.

    Captura de ecrã da opção de depuração no Visual Studio Code.

    Visual Studio Code abre um novo browser com Microsoft 365 Copilot. Se receber a solicitação, entre com sua conta do Microsoft 365.

No browser:

  1. No painel lateral, selecione o agente da-repairs-oauthlocal .

    Captura de ecrã do agente personalizado apresentado no Microsoft 365 Copilot.

  2. Na caixa de texto do pedido, escreva Show repair records assigned to Karin Blair e submeta o pedido.

    Dica

    Em vez de escrever o pedido, pode selecioná-lo a partir dos iniciadores de conversação.

    Captura de ecrã de uma conversação iniciada no agente declarativo personalizado.

  3. Confirme que pretende enviar dados para o plug-in da API com o botão Permitir sempre .

    Captura de ecrã do pedido para permitir o envio de dados para a API.

  4. Quando lhe for pedido, inicie sessão na API para continuar a utilizar a mesma conta que utiliza para iniciar sessão no seu inquilino do Microsoft 365 ao selecionar Iniciar sessão em da-repairs-oauthlocal.

    Captura de ecrã do pedido para iniciar sessão na aplicação que protege a API.

  5. Aguarde que o agente responda.

    Captura de ecrã a mostrar a resposta do agente declarativo ao pedido do utilizador.

Embora a sua API esteja acessível anonimamente porque está em execução no seu computador local, Microsoft 365 Copilot está a chamar a API autenticada conforme especificado na especificação da API. Pode verificar se o pedido contém um token de acesso ao definir um ponto de interrupção na função de reparações e ao submeter outro pedido no agente declarativo. Quando o código chegar ao ponto de interrupção, expanda a coleção req.headers e procure o cabeçalho de autorização que contém um JSON Web Token (JWT).

Captura de ecrã de Visual Studio Code com um ponto de interrupção e o painel de depuração a mostrar o cabeçalho de autorização no pedido recebido.

Pare a sessão de depuração no Visual Studio Code quando terminar o teste.