Übung: Integrieren eines API-Plug-Ins in eine API, die mit OAuth gesichert ist

Abgeschlossen

API-Plug-Ins für Microsoft 365 Copilot ermöglichen die Integration mit APIs, die mit OAuth geschützt sind. Sie behalten die Client-ID und das Geheimnis der App, die Ihre API schützt, sicher, indem Sie sie im Teams-Tresor registrieren. Zur Laufzeit führt Microsoft 365 Copilot Ihr Plug-In aus, ruft die Informationen aus dem Tresor ab und verwendet es, um ein Zugriffstoken abzurufen und die API aufzurufen. Wenn Sie diesen Prozess ausführen, bleiben die Client-ID und der geheime Schlüssel sicher und werden niemals für den Client verfügbar gemacht.

Öffnen des Beispielprojekts

Laden Sie zunächst das Beispielprojekt herunter:

  1. Navigieren Sie in einem Webbrowser zu https://aka.ms/learn-da-api-ts-repairs. Sie erhalten eine Aufforderung zum Herunterladen einer ZIP-Datei mit dem Beispielprojekt.
  2. Speichern Sie die ZIP-Datei auf Ihrem Computer.
  3. Extrahieren Sie den Inhalt der ZIP-Datei.
  4. Öffnen Sie den Ordner in Visual Studio Code.

Das Beispielprojekt ist ein Microsoft 365 Agents Toolkit-Projekt, das einen deklarativen Agent, ein API-Plug-In und eine API enthält, die mit Microsoft Entra ID gesichert ist. Die API wird auf Azure Functions ausgeführt und implementiert Sicherheit mithilfe der integrierten Authentifizierungs- und Autorisierungsfunktionen von Azure Functions, die manchmal als Easy Auth bezeichnet werden.

Untersuchen der OAuth2-Autorisierungskonfiguration

Bevor Sie fortfahren, überprüfen Sie die OAuth2-Autorisierungskonfiguration im Beispielprojekt.

Untersuchen der API-Definition

Sehen Sie sich zunächst die Sicherheitskonfiguration der API-Definition an, die im Projekt enthalten ist.

In Visual Studio Code:

  1. Öffnen Sie die Datei appPackage/apiSpecificationFile/repair.yml .

  2. Beachten Sie im Abschnitt components.securitySchemes die Eigenschaft 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 
    

    Die -Eigenschaft definiert ein OAuth2-Sicherheitsschema und enthält Informationen zu den URLs, die zum Abrufen eines Zugriffstokens aufgerufen werden sollen, und zu den von der API verwendeten Bereichen.

    Wichtig

    Beachten Sie, dass der Bereich mit dem Anwendungs-ID-URI (api://...) vollqualifiziert ist. Wenn Sie mit Microsoft Entra müssen Sie benutzerdefinierte Bereiche vollständig qualifizieren. Wenn Microsoft Entra einen nicht qualifizierten Bereich sieht, wird davon ausgegangen, dass er zu Microsoft Graph gehört, was zu Autorisierungsflussfehlern führt.

  3. Suchen Sie die Eigenschaft paths./repairs.get.security . Beachten Sie, dass es auf das oAuth2AuthCode-Sicherheitsschema und den Bereich verweist, den der Client zum Ausführen des Vorgangs benötigt.

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

    Wichtig

    Das Auflisten der erforderlichen Bereiche in der API-Spezifikation ist rein informativ. Bei der Implementierung der API sind Sie dafür verantwortlich, das Token zu überprüfen und zu überprüfen, ob es die erforderlichen Bereiche enthält.

Untersuchen der API-Implementierung

Sehen Sie sich als Nächstes die API-Implementierung an.

In Visual Studio Code:

  1. Öffnen Sie die Datei src/functions/repairs.ts .

  2. Suchen Sie in der Reparaturhandlerfunktion die folgende Zeile, die überprüft, ob die Anforderung ein Zugriffstoken mit den erforderlichen Bereichen enthält:

    if (!hasRequiredScopes(req, 'repairs_read')) {
      return {
        status: 403,
        body: "Insufficient permissions",
      };
    }
    
  3. Die funktion hasRequiredScopes wird weiter in der repairs.ts-Datei implementiert:

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

    Die Funktion extrahiert zunächst das Bearertoken aus dem Autorisierungsanforderungsheader. Als Nächstes wird das Paket jwt-decode verwendet, um das Token zu decodieren und die Liste der Bereiche aus dem scp-Anspruch abzurufen. Schließlich wird überprüft, ob der scp-Anspruch alle erforderlichen Bereiche enthält.

    Beachten Sie, dass die Funktion das Zugriffstoken nicht überprüft. Stattdessen wird nur überprüft, ob das Zugriffstoken die erforderlichen Bereiche enthält. In dieser Vorlage wird die API auf Azure Functions ausgeführt und implementiert die Sicherheit mithilfe von Easy Auth, die für die Überprüfung des Zugriffstokens zuständig ist. Wenn die Anforderung kein gültiges Zugriffstoken enthält, lehnt die Azure Functions Runtime es ab, bevor sie Ihren Code erreicht. Easy Auth überprüft zwar das Token, überprüft jedoch nicht die erforderlichen Bereiche, was Sie selbst tun müssen.

Untersuchen der Konfiguration des Tresortasks

In diesem Projekt verwenden Sie microsoft 365 Agents Toolkit, um die OAuth-Informationen zum Tresor hinzuzufügen. Microsoft 365 Agents Toolkit registriert die OAuth-Informationen im Tresor mithilfe einer speziellen Aufgabe in der Konfiguration des Projekts.

In Visual Studio Code:

  1. Öffnen Sie die Datei ./teampsapp.local.yml .

  2. Suchen Sie im Abschnitt bereitstellen den Task 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
    

    Der Task verwendet die Werte der TEAMS_APP_ID, AAD_APP_CLIENT_ID und SECRET_AAD_APP_CLIENT_SECRET Projektvariablen, die in den Dateien env/.env.local und env/.env.local.user gespeichert sind, und registriert sie im Tresor. Es aktiviert auch Proof Key for Code Exchange (PKCE) als zusätzliche Sicherheitsmaßnahme. Anschließend wird die Tresoreintrags-ID in die Umgebungsdatei env/.env.local geschrieben. Das Ergebnis dieser Aufgabe ist eine Umgebungsvariable namens OAUTH2AUTHCODE_CONFIGURATION_ID. Microsoft 365 Agents Toolkit schreibt den Wert dieser Variablen in die Datei appPackages/ai-plugin.json , die die Plug-In-Definition enthält. Zur Laufzeit verwendet der deklarative Agent, der das API-Plug-In lädt, diese ID, um die OAuth-Informationen aus dem Tresor abzurufen und den Authentifizierungsfluss zu starten, um ein Zugriffstoken abzurufen.

    Wichtig

    Die oauth/register-Aufgabe ist nur für die Registrierung der OAuth-Informationen im Tresor verantwortlich, wenn sie noch nicht vorhanden sind. Wenn die Informationen bereits vorhanden sind, überspringt das Microsoft 365 Agents Toolkit die Ausführung dieser Aufgabe.

  3. Suchen Sie als Nächstes die Aufgabe oauth/update .

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

    Der Task hält die OAuth-Informationen im Tresor mit Ihrem Projekt synchronisiert. Es ist erforderlich, dass Ihr Projekt ordnungsgemäß funktioniert. Eine der wichtigsten Eigenschaften ist die URL, unter der Ihr API-Plug-In verfügbar ist. Jedes Mal, wenn Sie Ihr Projekt starten, öffnet das Microsoft 365 Agents Toolkit einen Entwicklungstunnel unter einer neuen URL. Die OAuth-Informationen im Tresor müssen auf diese URL verweisen, damit Copilot Ihre API erreichen kann.

Untersuchen der Authentifizierungs- und Autorisierungskonfiguration

Als Nächstes werden die Authentifizierungs- und Autorisierungseinstellungen der Azure Functions untersucht. Die API in dieser Übung verwendet die integrierten Authentifizierungs- und Autorisierungsfunktionen von Azure Functions. Das Microsoft 365 Agents Toolkit konfiguriert diese Funktionen bei der Bereitstellung Azure Functions in Azure.

In Visual Studio Code:

  1. Öffnen Sie die Datei infra/azure.bicep .

  2. Suchen Sie die Ressource 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
              ]
            }
          }
        }
      }
    }
    

    Diese Ressource aktiviert die integrierten Authentifizierungs- und Autorisierungsfunktionen für die Azure Functions-App. Zunächst wird im Abschnitt globalValidation definiert, dass die App nur authentifizierte Anforderungen zulässt. Wenn die App eine nicht authentifizierte Anforderung empfängt, wird sie mit dem HTTP-Fehler 401 abgelehnt. Anschließend definiert die Konfiguration im Abschnitt identityProviders, dass sie Microsoft Entra ID (früher als Azure Active Directory bezeichnet) verwendet, um Anforderungen zu autorisieren. Es gibt an, welche Microsoft Entra App-Registrierung verwendet wird, um die API zu schützen, und welche Zielgruppen die API aufrufen dürfen.

Untersuchen der Microsoft Entra Anwendungsregistrierung

Der letzte zu untersuchende Teil ist die Microsoft Entra Anwendungsregistrierung, die das Projekt zum Sichern der API verwendet. Wenn Sie OAuth verwenden, sichern Sie den Zugriff auf Ressourcen mithilfe einer Anwendung. Die Anwendung definiert in der Regel Anmeldeinformationen, die zum Abrufen eines Zugriffstokens erforderlich sind, z. B. einen geheimen Clientschlüssel oder ein Zertifikat. Außerdem werden die verschiedenen Berechtigungen (auch als Bereiche bezeichnet) angegeben, die der Client beim Aufrufen der API anfordern kann. Microsoft Entra Anwendungsregistrierung stellt eine Anwendung in der Microsoft-Cloud dar und definiert eine Anwendung für die Verwendung mit OAuth-Autorisierungsflows.

In Visual Studio Code:

  1. Öffnen Sie die Datei ./aad.manifest.json .

  2. Suchen Sie die oauth2Permissions-Eigenschaft .

    "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"
      }
    ],
    

    Die -Eigenschaft definiert einen benutzerdefinierten Bereich namens repairs_read , der dem Client die Berechtigung zum Lesen von Reparaturen aus der Reparatur-API erteilt.

  3. Suchen Sie die identifierUris-Eigenschaft .

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

    Die identifierUris-Eigenschaft definiert einen Bezeichner, der verwendet wird, um den Bereich vollständig zu qualifizieren.

Testen Sie den deklarativen Agent mit dem API-Plug-In in Microsoft 365 Copilot

Der letzte Schritt besteht darin, den deklarativen Agent mit dem API-Plug-In in Microsoft 365 Copilot zu testen.

In Visual Studio Code:

  1. Aktivieren Sie auf der Aktivitätsleiste die Erweiterung Microsoft 365 Agents Toolkit .

  2. Stellen Sie im Bereich der Microsoft 365 Agents Toolkit-Erweiterung im Abschnitt Konten sicher, dass Sie bei Ihrem Microsoft 365-Mandanten mit aktiviertem Copilot angemeldet sind.

    Screenshot: Microsoft 365 Agents Toolkit mit der status der Verbindung mit Microsoft 365

  3. Wechseln Sie in der Aktivitätsleiste zur Ansicht Ausführen und Debuggen .

  4. Wählen Sie in der Liste der Konfigurationen Debuggen in Copilot (Edge) aus, und drücken Sie die Wiedergabeschaltfläche, um das Debuggen zu starten.

    Screenshot der Debugoption in Visual Studio Code.

    Visual Studio Code öffnet einen neuen Webbrowser mit Microsoft 365 Copilot. Wenn Sie dazu aufgefordert werden, melden Sie sich mit Ihrem Microsoft 365-Konto an.

Im Webbrowser:

  1. Wählen Sie im Seitenbereich den Agent da-repairs-oauthlocal aus.

    Screenshot des benutzerdefinierten Agents, der in Microsoft 365 Copilot angezeigt wird.

  2. Geben Sie im Eingabeaufforderungstextfeld die Eingabeaufforderung ein Show repair records assigned to Karin Blair , und übermitteln Sie sie.

    Tipp

    Anstatt die Eingabeaufforderung einzugeben, können Sie sie in den Unterhaltungsstartern auswählen.

    Screenshot einer Konversation, die im benutzerdefinierten deklarativen Agent gestartet wurde.

  3. Vergewissern Sie sich, dass Sie Daten an das API-Plug-In senden möchten, indem Sie die Schaltfläche Immer zulassen verwenden.

    Screenshot der Aufforderung, das Senden von Daten an die API zuzulassen.

  4. Wenn Sie dazu aufgefordert werden, melden Sie sich bei der API an, um weiterhin dasselbe Konto zu verwenden, das Sie für die Anmeldung bei Ihrem Microsoft 365-Mandanten verwenden, indem Sie Bei da-repairs-oauthlocal anmelden auswählen.

    Screenshot der Aufforderung zum Anmelden bei der App, die die API schützt.

  5. Warten Sie, bis der Agent antwortet.

    Screenshot der Antwort des deklarativen Agents auf die Eingabeaufforderung des Benutzers.

Obwohl auf Ihre API anonym zugegriffen werden kann, weil sie auf Ihrem lokalen Computer ausgeführt wird, ruft Microsoft 365 Copilot Ihre API auf, die gemäß der API-Spezifikation authentifiziert ist. Sie können überprüfen, ob die Anforderung ein Zugriffstoken enthält, indem Sie einen Haltepunkt in der Reparaturfunktion festlegen und eine weitere Eingabeaufforderung im deklarativen Agent übermitteln. Wenn der Code Ihren Haltepunkt erreicht, erweitern Sie die Req.headers-Auflistung, und suchen Sie nach dem Autorisierungsheader, der ein JSON-Webtoken (JWT) enthält.

Screenshot von Visual Studio Code mit einem Haltepunkt und dem Debugbereich mit dem Autorisierungsheader für die eingehende Anforderung.

Beenden Sie die Debugsitzung in Visual Studio Code, wenn Sie die Tests abgeschlossen haben.