Änderungsbenachrichtigungen mit Ressourcendaten einrichten

Microsoft Graph ermöglicht Apps das Abonnieren und Empfangen von Änderungsbenachrichtigungen für Ressourcen über verschiedene Übermittlungskanäle. Sie können Abonnements einrichten, um die geänderten Ressourcendaten (z. B. den Inhalt einer Microsoft Teams-Chat-Nachricht oder von Microsoft Teams-Anwesenheitsinformationen) in Änderungsbenachrichtigungen einzuschließen. Änderungsbenachrichtigungen, die die Ressourcenänderungsdaten enthalten, werden als umfangreiche Benachrichtigungen bezeichnet. Ihre App kann umfangreiche Benachrichtigungen verwenden, um Ihre Geschäftslogik auszuführen, ohne einen separaten API-Aufruf ausführen zu müssen, um die geänderte Ressource abzurufen.

Dieser Artikel führt Sie durch den Prozess zum Einrichten umfangreicher Benachrichtigungen in Ihrer Anwendung.

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 einem organization: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 organization: insgesamt 10.000 Abonnements.
  • Teams callTranscript Alle Transkripte in einem organization: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 organization: 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 rich-Benachrichtigung besteht aus allen Eigenschaften des geänderten instance.
    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 rich-Benachrichtigung besteht aus allen Eigenschaften des geänderten instance.
    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 rich-Benachrichtigung besteht aus allen Eigenschaften des geänderten instance.
    Teams team Änderungen an einem Team im Mandanten: /teams

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

    Ressourcendaten in Benachrichtigungs-Nutzlast

    Im Allgemeinen enthält diese Art von Änderungsbenachrichtigungen 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.

    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.

    Um ein Abonnement zu erstellen, das umfangreiche Benachrichtigungen enthält, müssen Sie die folgenden Eigenschaften angeben:

    • 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.
    • 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.

    Denken Sie dabei an Folgendes:

    • Überprüfen Sie beide Endpunkte wie in Ü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 Ressource instance 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

    Apps führen häufig Geschäftslogik basierend auf Ressourcendaten aus, die in Änderungsbenachrichtigungen enthalten sind. Es ist wichtig, zuerst die Echtheit jeder Änderungsbenachrichtigung zu überprüfen. Andernfalls kann ein Dritter Ihre App mit falschen Änderungsbenachrichtigungen täuschen und sie dazu bringen, die Geschäftslogik falsch auszuführen, 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. Dies ist akzeptabel, da Sie später vertrauenswürdige Microsoft Graph-Aufrufe ausführen können, um Zugriff auf Ressourcendaten zu erhalten, und daher die Auswirkung von Spoofing-Versuchen begrenzt ist.

    Führen Sie für Änderungsbenachrichtigungen, die Ressourcendaten bereitstellen, eine gründlichere Überprüfung durch, bevor Sie die Daten verarbeiten.

    In diesem Abschnitt:

    Ü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: Durch das Einrichten der Änderungsbenachrichtigungen, die über Azure Event Hubs übermittelt werden, sendet Microsoft Graph die Validierungstoken nicht. Microsoft Graph muss die notificationUrlnicht überprüfen.

    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": "84bd8158-6d4d-4958-8b9f-9d6445542f95",
                "changeType": "created",
                ...
            }
        ],
        "validationTokens": [
            "eyJ0eXAiOiJKV1QiLCJhb...",
            "cGlkYWNyIjoiMiIsImlkc..."
        ]
    }
    

    Hinweis: Eine vollständige Beschreibung der bei der Zustellung von Änderungsbenachrichtigungen gesendeten Daten finden Sie unter changeNotificationCollection.

    So führen Sie die Validierung durch

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

    Beachten Sie Folgendes:

    • Stellen Sie sicher, dass als Teil der Antwort auf die Änderungsbenachrichtigung immer ein HTTP 202 Accepted-Statuscode gesendet wird.
    • Antworten Sie, bevor Sie die Änderungsbenachrichtigung validieren (z. B. wenn Sie Änderungsbenachrichtigungen für die spätere Verarbeitung in Warteschlangen speichern) oder nachdem Sie sie (auf die Schnelle) verarbeitet haben, auch wenn die Validierung fehlgeschlagen ist.
    • 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 akzeptiert 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 und von der erwarteten Autorität ausgestellt wurde, Microsoft Identity Platform:

      • 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. Beachten Sie, dass die Konfiguration häufig aktualisiert wird, da die Signaturschlüssel täglich gewechselt 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

    Hier ist ein Beispiel für die im JWT-Token enthaltenen Eigenschaften, die für die Validierung 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 Kundendaten nicht von einem Drittanbieter entschlüsselt werden können, auch wenn dieser es schafft, die ursprünglichen Änderungsbenachrichtigungen abzufangen.

    In diesem Abschnitt:

    Verwalten von Verschlüsselungsschlüsseln

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

      • Sie können das Zertifikat selbst signieren, 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 als Lösung zum Erstellen, Rotieren und sicheren Verwalten von Zertifikaten. Stellen Sie sicher, dass die Schlüssel die folgenden Kriterien erfüllen:

        • Der Schlüssel muss vom Typ RSA sein,
        • 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:

      • Stellen Sie das Zertifikat in der encryptionCertificate-Eigenschaft unter Verwendung des base64-codierten Inhalts bereit, 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.

      • Tun Sie dies im Rahmen einer regelmäßigen Erneuerung des Abonnements.
      • 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 Folgendes:

      • 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 Sie das alte Zertifikat nur, wenn Sie keine neueren Änderungsbenachrichtigungen gesehen haben, die darauf verweisen.

    Entschlüsseln von Ressourcendaten

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

    • Es generiert einen symmetrischen Schlüssel für die einmalige Verwendung 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 ist eine Beispiel-Ä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..."
        ]
    }
    

    Hinweis: Eine vollständige Beschreibung der bei der Zustellung von Änderungsbenachrichtigungen gesendeten Daten finden Sie unter changeNotificationCollection.

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

    Entschlüsseln des symmetrischen Schlüssels

    // 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.