Freigeben über


Einrichten von Änderungsbenachrichtigungen, die Ressourcendaten enthalten (umfangreiche Benachrichtigungen)

Microsoft Graph ermöglicht Apps das Abonnieren und Empfangen von Benachrichtigungen über Änderungen an Ressourcen, an deren Verwendung sie interessiert sind. Sie können zwar die grundlegende Art von Änderungsbenachrichtigungen abonnieren, aber einige Ressourcen wie Microsoft Teams-Chatnachrichten und Anwesenheitsressourcen unterstützen umfangreiche Benachrichtigungen.

Zu den umfangreichen Benachrichtigungen gehören die geänderten Ressourcendaten, sodass Ihre App Geschäftslogik ausführen kann, ohne einen separaten API-Aufruf ausführen zu müssen, um die geänderte Ressource abzurufen. In diesem Artikel erfahren Sie, wie Sie umfangreiche Benachrichtigungen in Ihrer Anwendung einrichten.

Unterstützte Ressourcen

Umfangreiche Benachrichtigungen sind für die folgenden Ressourcen verfügbar.

Hinweis

Umfangreiche Benachrichtigungen für Abonnements für Endpunkte, die mit einem Sternchen (*) gekennzeichnet sind, sind nur auf dem /beta Endpunkt verfügbar.

Ressource Unterstützte Ressourcenpfade Begrenzungen
Outlook-Ereignis Änderungen an allen Ereignissen im Postfach eines Benutzers: /users/{id}/events Erfordert $select , dass nur eine Teilmenge der Eigenschaften in der rich-Benachrichtigung zurückgegeben wird. Weitere Informationen finden Sie unter Ändern von Benachrichtigungen für Outlook-Ressourcen.
Outlook-Nachricht Änderungen an allen Nachrichten im Postfach eines Benutzers: /users/{id}/messages

Änderungen an Nachrichten im Posteingang eines Benutzers: /users/{id}/mailFolders/{id}/messages
Erfordert $select , dass nur eine Teilmenge der Eigenschaften in der rich-Benachrichtigung zurückgegeben wird. Weitere Informationen finden Sie unter Ändern von Benachrichtigungen für Outlook-Ressourcen.
Persönlicher Outlook-Kontakt Änderungen an allen persönlichen Kontakten im Postfach eines Benutzers: /users/{id}/contacts

Änderungen an allen persönlichen Kontakten im contactFolder eines Benutzers: /users/{id}/contactFolders/{id}/contacts
Erfordert $select , dass nur eine Teilmenge der Eigenschaften in der rich-Benachrichtigung zurückgegeben wird. Weitere Informationen finden Sie unter Ändern von Benachrichtigungen für Outlook-Ressourcen.
Teams-AnrufAufzeichnung Alle Aufzeichnungen in einer Organisation: communications/onlineMeetings/getAllRecordings

Alle Aufzeichnungen für eine bestimmte Besprechung: communications/onlineMeetings/{onlineMeetingId}/recordings

Eine Anrufaufzeichnung, die in einer Besprechung verfügbar wird, die von einem bestimmten Benutzer organisiert wird: users/{id}/onlineMeetings/getAllRecordings

Eine Anrufaufzeichnung, die in einer Besprechung verfügbar wird, in der eine bestimmte Teams-App installiert ist: appCatalogs/teamsApps/{id}/installedToOnlineMeetings/getAllRecordings *
Maximale Abonnementkontingente:
  • Kombination pro App und Onlinebesprechung: 1
  • Kombination pro App und Benutzer: 1
  • Pro Benutzer (für Abonnements, die Aufzeichnungen in allen onlineMeetings nachverfolgen, die vom Benutzer organisiert werden): 10 Abonnements.
  • Pro Organisation: insgesamt 10.000 Abonnements.
  • Teams callTranscript Alle Transkripte in einer Organisation: communications/onlineMeetings/getAllTranscripts

    Alle Transkripte für eine bestimmte Besprechung: communications/onlineMeetings/{onlineMeetingId}/transcripts

    Ein Anruftranskript, das in einer Besprechung verfügbar wird, die von einem bestimmten Benutzer organisiert wird: users/{id}/onlineMeetings/getAllTranscripts

    Ein Anruftranskript, das in einer Besprechung verfügbar wird, in der eine bestimmte Teams-App installiert ist: appCatalogs/teamsApps/{id}/installedToOnlineMeetings/getAllTrancripts *
    Maximale Abonnementkontingente:
  • Kombination pro App und Onlinebesprechung: 1
  • Kombination pro App und Benutzer: 1
  • Pro Benutzer (für Abonnements, die Transkripte in allen vom Benutzer organisierten onlineMeetings nachverfolgen): 10 Abonnements.
  • Pro Organisation: insgesamt 10.000 Abonnements.
  • Teams channel Änderungen an Kanälen in allen Teams: /teams/getAllChannels

    Änderungen am Kanal in einem bestimmten Team: /teams/{id}/channels
    -
    Teams Chat Änderungen an chatten im Mandanten: /chats

    Änderungen an einem bestimmten Chat: /chats/{id}
    -
    Teams chatMessage Änderungen an Chatnachrichten in allen Kanälen in allen Teams: /teams/getAllMessages

    Änderungen an Chatnachrichten in einem bestimmten Kanal: /teams/{id}/channels/{id}/messages

    Änderungen an Chatnachrichten in allen Chats: /chats/getAllMessages

    Änderungen an Chatnachrichten in einem bestimmten Chat: /chats/{id}/messages

    Änderungen an Chatnachrichten in allen Chats, zu der ein bestimmter Benutzer gehört: /users/{id}/chats/getAllMessages
    Unterstützt nicht die Verwendung von $select , um nur ausgewählte Eigenschaften zurückzugeben. Die umfangreiche Benachrichtigung besteht aus allen Eigenschaften der geänderten Instanz.
    Teams conversationMember Änderungen an der Mitgliedschaft in einem bestimmten Team: /teams/{id}/members



    Änderungen an der Mitgliedschaft in einem bestimmten Chat: /chats/{id}/members
    -
    Teams onlineMeeting * Änderungen an einer Onlinebesprechung: /communications/onlineMeetings/?$filter=JoinWebUrl eq '{joinWebUrl} * Unterstützt nicht die Verwendung von $select , um nur ausgewählte Eigenschaften zurückzugeben. Die umfangreiche Benachrichtigung besteht aus allen Eigenschaften der geänderten Instanz.
    Teams-Anwesenheit Änderungen an der Anwesenheit eines einzelnen Benutzers: /communications/presences/{id} Unterstützt nicht die Verwendung von $select , um nur ausgewählte Eigenschaften zurückzugeben. Die umfangreiche Benachrichtigung besteht aus allen Eigenschaften der geänderten Instanz.
    Teams team Änderungen an einem Team im Mandanten: /teams

    Änderungen an einem bestimmten Team: /teams/{id}
    -

    Ressourcendaten in Benachrichtigungs-Nutzlast

    Umfangreiche Benachrichtigungen enthalten die folgenden Ressourcendaten in der Nutzlast:

    • Die ID und der Typ der geänderten Ressourceninstanz, die in der Eigenschaft resourceData zurückgegeben werden.
    • Alle Eigenschaftswerte dieser Ressourceninstanz, die wie im Abonnement angegeben verschlüsselt sind, werden in der Eigenschaft encryptedContent zurückgegeben.
    • Oder je nach Ressource bestimmte Eigenschaften, die in der Eigenschaft resourceData zurückgegeben werden. Um nur bestimmte Eigenschaften abzurufen, geben Sie diese mithilfe eines $selectParameters als Teil der Ressourcen-URL im Abonnement an.

    Erstellen eines Abonnements

    Umfangreiche Benachrichtigungen werden auf die gleiche Weise wie grundlegende Änderungsbenachrichtigungen eingerichtet, mit der Ausnahme, dass Sie die folgenden zusätzlichen Eigenschaften angeben müssen :

    • includeResourceData, das auf true gesetzt werden sollte, um Ressourcendaten explizit anzufordern.
    • encryptionCertificate , das nur den öffentlichen Schlüssel enthält, den Microsoft Graph zum Verschlüsseln der Ressourcendaten verwendet, die an Ihre App zurückgegeben werden. Aus Sicherheitsgründen verschlüsselt Microsoft Graph die Ressourcendaten, die in einer umfassenden Benachrichtigung zurückgegeben werden. Sie müssen beim Erstellen des Abonnements einen öffentlichen Verschlüsselungsschlüssel angeben. Weitere Informationen zum Erstellen und Verwalten von Verschlüsselungsschlüsseln finden Sie unter Entschlüsseln von Ressourcendaten aus Änderungsbenachrichtigungen.
    • encryptionCertificateId, ist Ihre eigene Kennung für das Zertifikat. Verwenden Sie diese ID, um in jeder Änderungsbenachrichtigung zu ermitteln, welches Zertifikat für die Entschlüsselung verwendet werden soll.

    Sie müssen auch beide Endpunkte überprüfen, wie unter Überprüfung des Benachrichtigungsendpunkts beschrieben. Wenn Sie die gleiche URL für beide Endpunkte verwenden, erhalten Sie und sollten auf zwei Validierungsanforderungen antworten.

    Beispiel für eine Abonnementanfrage

    Das folgende Beispiel abonniert Kanalnachrichten, die in Microsoft Teams erstellt oder aktualisiert werden.

    POST https://graph.microsoft.com/v1.0/subscriptions
    Content-Type: application/json
    
    {
      "changeType": "created,updated",
      "notificationUrl": "https://webhook.azurewebsites.net/api/resourceNotifications",
      "resource": "/teams/{id}/channels/{id}/messages",
      "includeResourceData": true,
      "encryptionCertificate": "{base64encodedCertificate}",
      "encryptionCertificateId": "{customId}",
      "expirationDateTime": "2019-09-19T11:00:00.0000000Z",
      "clientState": "{secretClientState}"
    }
    

    Abonnementantwort

    HTTP/1.1 201 Created
    Content-Type: application/json
    
    {
      "changeType": "created,updated",
      "notificationUrl": "https://webhook.azurewebsites.net/api/resourceNotifications",
      "resource": "/teams/{id}/channels/{id}/messages",
      "includeResourceData": true,
      "encryptionCertificateId": "{custom ID}",
      "expirationDateTime": "2019-09-19T11:00:00.0000000Z",
      "clientState": "{secret client state}"
    }
    

    Benachrichtigungen zum Abonnementlebenszyklus

    Bestimmte Ereignisse können den normalen Fluss von Änderungsbenachrichtigungen in einem vorhandenen Abonnement beeinträchtigen. Benachrichtigungen zum Abonnementlebenszyklus informieren Sie über Maßnahmen, die zur Aufrechterhaltung eines unterbrechungsfreien Flusses erforderlich sind. Im Gegensatz zu einer Ressourcenänderungsbenachrichtigung, die eine Änderung an einer Ressourceninstanz informiert, bezieht sich eine Lebenszyklusbenachrichtigung auf das Abonnement selbst und seinen aktuellen Status im Lebenszyklus.

    Weitere Informationen zum Empfangen und Reagieren auf Lebenszyklusbenachrichtigungen finden Sie unter Reduzieren fehlender Abonnements und Änderungsbenachrichtigungen.

    Überprüfung der Echtheit von Benachrichtigungen

    Bevor Sie Geschäftslogik basierend auf Ressourcendaten ausführen, die in Änderungsbenachrichtigungen enthalten sind, müssen Sie zunächst die Authentizität jeder Änderungsbenachrichtigung überprüfen. Andernfalls kann ein Drittanbieter Ihre App mit falschen Änderungsbenachrichtigungen spoofen und dazu bringen, dass ihre Geschäftslogik falsch ausgeführt wird, was zu einem Sicherheitsvorfall führen kann.

    Für grundlegende Änderungsbenachrichtigungen, die keine Ressourcendaten enthalten, überprüfen Sie diese einfach basierend auf dem ClientState-Wert , wie unter Verarbeiten der Änderungsbenachrichtigung beschrieben. Diese Überprüfung ist akzeptabel, da Sie nachfolgende vertrauenswürdige Microsoft Graph-Aufrufe durchführen können, um Zugriff auf Ressourcendaten zu erhalten, sodass die Auswirkungen von Spoofingversuchen begrenzt sind.

    Führen Sie für umfangreiche Benachrichtigungen eine gründlichere Überprüfung durch, bevor Sie die Daten verarbeiten.

    In diesem Abschnitt untersuchen Sie die folgenden Validierungskonzepte:

    Überprüfungstoken in der Änderungsbenachrichtigung

    Eine Änderungsbenachrichtigung mit Ressourcendaten enthält die zusätzliche Eigenschaft validationTokens, die ein array von JSON Web Token (JWT) enthält, das von Microsoft Graph generiert wird. Microsoft Graph generiert ein einzelnes Token für jedes unterschiedliche App- und Mandantenpaar, für das ein Element im Wertarray vorhanden ist. Beachten Sie, dass Änderungsbenachrichtigungen eine Mischung aus Elementen für verschiedene Apps und Mandanten enthalten können, die mit derselben notificationUrl abonniert haben.

    Hinweis

    Microsoft Graph sendet keine Validierungstoken für Änderungsbenachrichtigungen, die über Azure Event Hubs übermittelt werden , da der Abonnementdienst die notificationUrl für Event Hubs nicht überprüfen muss.

    Im folgenden Beispiel enthält die Änderungsbenachrichtigung zwei Elemente für dieselbe App und für zwei verschiedene Mandanten. Daher enthält das validationTokens-Array zwei Token, die validiert werden müssen.

    {
        "value": [
            {
                "subscriptionId": "76619225-ff6b-4489-96ca-4ef547e78b22",
                "tenantId": "aaaabbbb-0000-cccc-1111-dddd2222eeee",
                "changeType": "created",
                ...
            },
            {
                "subscriptionId": "5cfe2387-163c-4006-81bb-1b5e1e060afe",
                "tenantId": "bbbbcccc-1111-dddd-2222-eeee3333ffff",
                "changeType": "created",
                ...
            }
        ],
        "validationTokens": [
            "eyJ0eXAiOiJKV1QiLCJhb...",
            "cGlkYWNyIjoiMiIsImlkc..."
        ]
    }
    

    Das Änderungsbenachrichtigungsobjekt befindet sich in der Struktur des Ressourcentyps changeNotificationCollection.

    So führen Sie die Validierung durch

    Verwenden Sie die Microsoft Authentication Library (MSAL), um die Tokenüberprüfung oder eine Drittanbieterbibliothek für eine andere Plattform zu verarbeiten.

    Beachten Sie die folgenden Prinzipien:

    • Stellen Sie sicher, dass als Teil der Antwort auf die Änderungsbenachrichtigung immer ein HTTP 202 Accepted-Statuscode gesendet wird.
    • Reagieren Sie, bevor Sie die Änderungsbenachrichtigung überprüfen, auch wenn die Überprüfung später fehlschlägt. Das heißt, Sie erhalten sofort die Änderungsbenachrichtigung, unabhängig davon, ob Sie Benachrichtigungen zur späteren Verarbeitung in Warteschlangen speichern oder sie direkt verarbeiten.
    • Das Akzeptieren einer Änderungsbenachrichtigung verhindert unnötige Zustellungswiederholungen und verhindert, dass potenzielle kriminelle Akteure herausfinden, ob sie die Validierung bestanden haben oder nicht. Sie können eine ungültige Änderungsbenachrichtigung jederzeit ignorieren, nachdem Sie sie erhalten haben.

    Führen Sie insbesondere die Überprüfung für jedes JWT-Token in der validationTokens-Sammlung aus. Wenn Token fehlschlagen, betrachten Sie die Änderungsbenachrichtigung als verdächtig und untersuchen Sie sie weiter.

    Führen Sie die folgenden Schritte aus, um Token und Apps zu validieren, die Token generieren:

    1. Überprüfen Sie, ob das Token nicht abgelaufen ist.

    2. Überprüfen Sie, ob das Token nicht manipuliert wurde und von der erwarteten Autorität Microsoft Identity Platform ausgestellt wurde:

      • Beziehen Sie die Signaturschlüssel vom gemeinsamen Konfigurationsendpunkt:https://login.microsoftonline.com/common/.well-known/openid-configuration Diese Konfiguration wird von Ihrer App für einige Zeit zwischengespeichert. Die Konfiguration wird häufig aktualisiert, da Signaturschlüssel täglich rotiert werden.
      • Überprüfen Sie die Signatur des JWT-Tokens mit diesen Schlüsseln.

      Akzeptieren Sie keine Token, die von einer anderen Autorität ausgestellt wurden.

    3. Überprüfen Sie, ob das Token für Ihre App, die Änderungsbenachrichtigungen abonniert, ausgestellt wurde.

      Die folgenden Schritte sind Teil der Standardüberprüfungslogik in JWT-Token-Bibliotheken und können normalerweise als einzelner Funktionsaufruf ausgeführt werden.

      • Überprüfen Sie, ob die "Zielgruppe" im Token mit Ihrer App-ID übereinstimmt.
      • Wenn mehr als eine App Änderungsbenachrichtigungen erhält, überprüfen Sie, ob mehrere IDs vorhanden sind.
    4. Kritisch: Stellen Sie sicher, dass die App, die das Token generiert hat, den Herausgeber der Microsoft Graph-Änderungsbenachrichtigung darstellt.

      • Überprüfen Sie, ob die appid-Eigenschaft im Token mit dem erwarteten Wert von 0bf30f3b-4a52-48df-9a82-234910c4a086 übereinstimmt.
      • Dadurch wird sichergestellt, dass Änderungsbenachrichtigungen nicht von einer anderen App gesendet werden, die nicht Microsoft Graph ist.

    Beispiel für ein JWT-Token

    Das folgende Beispiel zeigt die Eigenschaften, die im JWT-Token enthalten sind, die für die Überprüfung benötigt werden.

    {
      // aud is your app's id 
      "aud": "8e460676-ae3f-4b1e-8790-ee0fb5d6148f",                           
      "iss": "https://sts.windows.net/84bd8158-6d4d-4958-8b9f-9d6445542f95/",
      "iat": 1565046813,
      "nbf": 1565046813,
      // Expiration date 
      "exp": 1565075913,                                                        
      "aio": "42FgYKhZ+uOZrHa7p+7tfruauq1HAA==",
      // appid represents the notification publisher and must always be the same value of 0bf30f3b-4a52-48df-9a82-234910c4a086 
      "appid": "0bf30f3b-4a52-48df-9a82-234910c4a086",                          
      "appidacr": "2",
      "idp": "https://sts.windows.net/84bd8158-6d4d-4958-8b9f-9d6445542f95/",
      "tid": "84bd8158-6d4d-4958-8b9f-9d6445542f95",
      "uti": "-KoJHevhgEGnN4kwuixpAA",
      "ver": "1.0"
    }
    

    Beispiel: Überprüfen von Überprüfungstoken

    // add Microsoft.IdentityModel.Protocols.OpenIdConnect and System.IdentityModel.Tokens.Jwt nuget packages to your project
    public async Task<bool> ValidateToken(string token, string tenantId, IEnumerable<string> appIds)
    {
        var configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>("https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration", new OpenIdConnectConfigurationRetriever());
        var openIdConfig = await configurationManager.GetConfigurationAsync();
        var handler = new JwtSecurityTokenHandler();
        try
        {
        handler.ValidateToken(token, new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateIssuerSigningKey = true,
            ValidateLifetime = true,
            ValidIssuer = $"https://sts.windows.net/{tenantId}/",
            ValidAudiences = appIds,
            IssuerSigningKeys = openIdConfig.SigningKeys
        }, out _);
        return true;
        }
        catch (Exception ex)
        {
        Trace.TraceError($"{ex.Message}:{ex.StackTrace}");
        return false;
        }
    }
    

    Entschlüsseln von Ressourcendaten aus Änderungsbenachrichtigungen

    Die resourceData-Eigenschaft einer Änderungsbenachrichtigung enthält nur die grundlegenden ID- und Typinformationen einer Ressourceninstanz. Die Eigenschaft encryptedData enthält die vollständigen Ressourcendaten, die von Microsoft Graph mit dem im Abonnement angegebenen öffentlichen Schlüssel verschlüsselt wurden. Die Eigenschaft enthält auch Werte, die für die Überprüfung und Entschlüsselung erforderlich sind. Dies geschieht, um die Sicherheit der Kundendaten zu erhöhen, auf die über Änderungsbenachrichtigungen zugegriffen wird. Es liegt in Ihrer Verantwortung, den privaten Schlüssel zu schützen, um sicherzustellen, dass ein Dritter die Kundendaten nicht entschlüsseln kann, auch wenn er es schafft, die ursprünglichen Änderungsbenachrichtigungen abzufangen.

    In diesem Abschnitt lernen Sie die folgenden Konzepte kennen:

    Verwalten von Verschlüsselungsschlüsseln

    1. Beziehen Sie ein Zertifikat mit einem Paar asymmetrischer Schlüssel.

      • Sie können ein selbstsigniertes Zertifikat verwenden, da Microsoft Graph den Zertifikataussteller nicht überprüft und den öffentlichen Schlüssel nur für die Verschlüsselung verwendet.

      • Verwenden Sie Azure Key Vault , um Zertifikate zu erstellen, zu rotieren und sicher zu verwalten. Stellen Sie sicher, dass die Schlüssel die folgenden Kriterien erfüllen:

        • Der Schlüssel muss vom Typ RSAsein.
        • Die Schlüsselgröße muss zwischen 2.048 Bit und 4.096 Bits sein.
    2. Exportieren Sie das Zertifikat im Base64-codierten X.509-Format, und schließen Sie nur den öffentlichen Schlüssel ein.

    3. Beim Erstellen eines Abonnements:

      • Geben Sie das Zertifikat in der encryptionCertificate-Eigenschaft an, indem Sie den Base64-codierten Inhalt verwenden, in den das Zertifikat exportiert wurde.

      • Geben Sie Ihre eigene Kennung in der Eigenschaft encryptionCertificateId an.

        Mit dieser Kennung können Sie Ihre Zertifikate mit den empfangenen Änderungsbenachrichtigungen abgleichen und Zertifikate aus Ihrem Zertifikatspeicher abrufen. Die Kennung darf bis zu 128 Zeichen umfassen.

    4. Verwalten Sie den privaten Schlüssel sicher, sodass Ihr Verarbeitungscode für Änderungsbenachrichtigungen auf den privaten Schlüssel zugreifen kann, um Ressourcendaten zu entschlüsseln.

    Rotierende Schlüssel

    Ändern Sie Ihre asymmetrischen Schlüssel regelmäßig, um das Risiko einer Gefährdung eines privaten Schlüssels zu minimieren. Befolgen Sie diese Schritte, um ein neues Schlüsselpaar einzuführen:

    1. Beziehen Sie ein neues Zertifikat mit einem neuen Paar asymmetrischer Schlüssel. Verwenden Sie es für alle neuen Abonnements, die erstellt werden.

    2. Aktualisieren Sie vorhandene Abonnements mit dem neuen Zertifikatschlüssel.

      • Machen Sie dieses Update als Teil der regulären Abonnementverlängerung.
      • Oder listen Sie alle Abonnements auf und geben Sie den Schlüssel an. Verwenden Sie den Patch-Vorgang für das Abonnement, und aktualisieren Sie die encryptionCertificate- und encryptionCertificateId-Eigenschaften.
    3. Beachten Sie die folgenden Prinzipien:

      • Für einige Zeit kann das alte Zertifikat noch für die Verschlüsselung verwendet werden. Ihre App muss sowohl auf alte als auch auf neue Zertifikate zugreifen können, um Inhalte entschlüsseln zu können.
      • Verwenden Sie die encryptionCertificateId-Eigenschaft in jeder Änderungsbenachrichtigung, um den zu verwendenden richtigen Schlüssel zu identifizieren.
      • Verwerfen des alten Zertifikats nur, wenn keine aktuellen Änderungsbenachrichtigungen angezeigt werden, die darauf verweisen.

    Entschlüsseln von Ressourcendaten

    Um die Leistung zu optimieren, verwendet Microsoft Graph einen zweistufigen Verschlüsselungsprozess:

    • Es generiert einen symmetrischen Single-Use-Schlüssel und verwendet ihn zum Verschlüsseln von Ressourcendaten.
    • Es verwendet den öffentlichen asymmetrischen Schlüssel (den Sie beim Abonnieren angegeben haben), um den symmetrischen Schlüssel zu verschlüsseln, und bezieht ihn in jede Änderungsbenachrichtigung über dieses Abonnement ein.

    Nehmen Sie immer an, dass der symmetrische Schlüssel für jedes Element in der Änderungsbenachrichtigung unterschiedlich ist.

    Um Ressourcendaten zu entschlüsseln, sollte Ihre App die umgekehrten Schritte ausführen und die Eigenschaften unter encryptedContent in jeder Änderungsbenachrichtigung verwenden:

    1. Verwenden Sie die Eigenschaft encryptionCertificateId um das zu verwendende Zertifikat zu identifizieren.

    2. Initialisieren Sie eine RSA-Verschlüsselungskomponente (z. B. den .NET RSACryptoServiceProvider) mit dem privaten Schlüssel.

    3. Entschlüsseln Sie den symmetrischen Schlüssel, der in der Eigenschaft dataKey jedes Elements in der Änderungsbenachrichtigung bereitgestellt wird.

      Verwenden Sie Optimal Asymmetric Encryption Padding (OAEP) für den Entschlüsselungsalgorithmus.

    4. Verwenden Sie den symmetrischen Schlüssel, um die HMAC-SHA256-Signatur des Werts in Daten zu berechnen.

      Vergleichen Sie es mit dem Wert in dataSignature. Wenn sie nicht übereinstimmen, gehen Sie davon aus, dass die Nutzlast manipuliert wurde, und entschlüsseln Sie sie nicht.

    5. Verwenden Sie den symmetrischen Schlüssel mit einem Advanced Encryption Standard (AES) (z. B. .NET AesCryptoServiceProvider), um den Inhalt in Daten zu entschlüsseln.

      • Verwenden Sie die folgenden Entschlüsselungsparameter für den AES-Algorithmus:

        • Padding: PKCS7
        • Cipher-Modus: CBC
      • Stellen Sie den "Initialisierungsvektor" ein, indem Sie die ersten 16 Bytes des zur Entschlüsselung verwendeten symmetrischen Schlüssels kopieren.

    6. Der entschlüsselte Wert ist eine JSON-Zeichenfolge, die die Ressourceninstanz in der Änderungsbenachrichtigung darstellt.

    Beispiel: Entschlüsseln einer Benachrichtigung mit verschlüsselten Ressourcendaten

    Das folgende JSON-Beispiel zeigt eine Änderungsbenachrichtigung, die verschlüsselte Eigenschaftswerte einer chatMessage-Instanz in einer Kanalnachricht enthält. Die Instanz wird durch den @odata.id Wert angegeben.

    {
        "value": [
            {
                "subscriptionId": "76222963-cc7b-42d2-882d-8aaa69cb2ba3",
                "changeType": "created",
                // Other properties typical in a resource change notification
                "resource": "teams('d29828b8-c04d-4e2a-b2f6-07da6982f0f0')/channels('19:f127a8c55ad949d1a238464d22f0f99e@thread.skype')/messages('1565045424600')/replies('1565047490246')",
                "resourceData": {
                    "id": "1565293727947",
                    "@odata.type": "#Microsoft.Graph.ChatMessage",
                    "@odata.id": "teams('88cbc8fc-164b-44f0-b6a6-b59b4a1559d3')/channels('19:8d9da062ec7647d4bb1976126e788b47@thread.tacv2')/messages('1565293727947')/replies('1565293727947')"
                },
                "encryptedContent": {
                    "data": "{encrypted data that produces a full resource}",
            "dataSignature": "<HMAC-SHA256 hash>",
                    "dataKey": "{encrypted symmetric key from Microsoft Graph}",
                    "encryptionCertificateId": "MySelfSignedCert/DDC9651A-D7BC-4D74-86BC-A8923584B0AB",
                    "encryptionCertificateThumbprint": "07293748CC064953A3052FB978C735FB89E61C3D"
                }
            }
        ],
        "validationTokens": [
            "eyJ0eXAiOiJKV1QiLCJhbGciOiJSU..."
        ]
    }
    

    Eine vollständige Beschreibung der Daten, die beim Senden von Änderungsbenachrichtigungen gesendet werden, finden Sie unter changeNotificationCollection-Ressourcentyp.

    Entschlüsseln des symmetrischen Schlüssels

    Dieser Abschnitt enthält einige nützliche Codefragmente, die C# und .NET für jede Entschlüsselungsstufe verwenden.

    // Initialize with the private key that matches the encryptionCertificateId.
    RSACryptoServiceProvider rsaProvider = ...;        
    byte[] encryptedSymmetricKey = Convert.FromBase64String(<value from dataKey property>);
    
    // Decrypt using OAEP padding.
    byte[] decryptedSymmetricKey = rsaProvider.Decrypt(encryptedSymmetricKey, fOAEP: true);
    
    // Can now use decryptedSymmetricKey with the AES algorithm.
    

    Vergleichen von Datensignaturen mit HMAC-SHA256

    byte[] decryptedSymmetricKey = <the aes key decrypted in the previous step>;
    byte[] encryptedPayload = <the value from the data property, still encrypted>;
    byte[] expectedSignature = <the value from the dataSignature property>;
    byte[] actualSignature;
    
    using (HMACSHA256 hmac = new HMACSHA256(decryptedSymmetricKey))
    {
        actualSignature = hmac.ComputeHash(encryptedPayload);
    }
    if (actualSignature.SequenceEqual(expectedSignature))
    {
        // Continue with decryption of the encryptedPayload.
    }
    else
    {
        // Do not attempt to decrypt encryptedPayload. Assume notification payload has been tampered with and investigate.
    }
    

    Entschlüsseln des Inhalts der Ressourcendaten

    AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider();
    aesProvider.Key = decryptedSymmetricKey;
    aesProvider.Padding = PaddingMode.PKCS7;
    aesProvider.Mode = CipherMode.CBC;
    
    // Obtain the intialization vector from the symmetric key itself.
    int vectorSize = 16;
    byte[] iv = new byte[vectorSize];
    Array.Copy(decryptedSymmetricKey, iv, vectorSize);
    aesProvider.IV = iv;
    
    byte[] encryptedPayload = Convert.FromBase64String(<value from data property>);
    
    string decryptedResourceData;
    // Decrypt the resource data content.
    using (var decryptor = aesProvider.CreateDecryptor())
    {
      using (MemoryStream msDecrypt = new MemoryStream(encryptedPayload))
      {
          using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
          {
              using (StreamReader srDecrypt = new StreamReader(csDecrypt))
              {
                  decryptedResourceData = srDecrypt.ReadToEnd();
              }
          }
      }
    }
    
    // decryptedResourceData now contains a JSON string that represents the resource.