Отсутствуют ValidationTokens в уведомлении, полученном от Microsoft Graph Webhook

Мы используем веб-перехватчики Microsoft Graph (бета-версия), чтобы получать уведомления об изменениях присутствия в Microsoft Teams, и в настоящее время у нашего клиента есть проблема. Когда мы получаем уведомление об изменении присутствия от Graph API, оно не содержит свойства validationTokens, поэтому проверка и последующая обработка завершаются неудачей. Наш код похож на образец предоставлен Microsoft.

Содержание полученного запроса у заказчика (упрощенное/сокращенное) выглядит следующим образом:

{
   "value": [
      {
         "subscriptionId": "...",
         "clientState": "...",
         "changeType": "updated",
         "resource": "communications/presences?$filter=id+in+(...)",
         "subscriptionExpirationDateTime": "2021-04-22T02:06:56.2872368-07:00",
         "resourceData": {
            "@odata.id": "communications/presences?$filter=id+in+(...)",
            "@odata.type": "#Microsoft.Graph.presence",
            "id": "..."
         },
         "tenantId": "...",
         "encryptedContent": {
            "data": "...",
            "dataSignature": "...",
            "dataKey": "...",
            "encryptionCertificateId": "3",
            "encryptionCertificateThumbprint": "..."
         }
      }
   ]
}

По сравнению с нашей лабораторией в теле запроса отсутствует свойство validationTokens:

{
   "value": [
      {
         "subscriptionId": "...",
         "clientState": "...",
         "changeType": "updated",
         "resource": "communications/presences?$filter=id+in+(...)",
         "subscriptionExpirationDateTime": "2021-04-26T00:07:08.9251516-07:00",
         "resourceData": {
            "@odata.id": "communications/presences?$filter=id+in+(...)",
            "@odata.type": "#Microsoft.Graph.presence",
            "id": "..."
         },
         "tenantId": "...",
         "encryptedContent": {
            "data": "...",
            "dataSignature": "...",
            "dataKey": "...",
            "encryptionCertificateId": "3",
            "encryptionCertificateThumbprint": "..."
         }
      }
   ],
   "validationTokens": [
      "..."
   ]
}

Согласно документу. , validationTokens предоставляются только для уведомлений об изменениях с данными о ресурсах — что здесь имеет место, поэтому мы предполагаем, что validationTokens должен присутствовать?

Любые подсказки приветствуются.

Изменить Вот сокращенный код, используемый для десериализации тела запроса/обработки запроса уведомления:

      <HttpPost("/Notification/{connectorId}/{apiLinkId}")>
      Public Async Function Listen(connectorId As Guid, apiLinkId As Guid, <FromQuery> Optional validationToken As String = Nothing) As Task(Of IActionResult)
         If Not String.IsNullOrEmpty(validationToken) Then
            ' Validate the new subscription by sending the token back to Microsoft Graph.
            ' This response is required for each subscription.
            Return Content(WebUtility.HtmlEncode(validationToken))
         End If

         Try
            ' Parse the received notifications.
            Dim options As New JsonSerializerOptions With {.PropertyNameCaseInsensitive = True}
            options.Converters.Add(New JsonStringEnumConverter(JsonNamingPolicy.CamelCase))

            Dim plainNotifications As New Dictionary(Of String, ChangeNotification)()
            Dim notificationCollection = Await JsonSerializer.DeserializeAsync(Of ChangeNotificationCollection)(Request.Body, options)
            notificationCollection.Value _
               .Where(Function(x) x.EncryptedContent Is Nothing) _
               .ForEach(Sub(notification)
                           Dim subscription = Stores.TeamsPresenceSubscriptionStore.Instance.GetValueOrDefault(notification.SubscriptionId.Value)

                           ' Verify the current client state matches the one that was sent.
                           If subscription Is Nothing OrElse notification.ClientState <> subscription.SecretClientState Then
                              Log.msg(Category.TEAMS, "Error: Failed to verify notification")
                              Return
                           End If

                           ' Just keep the latest notification for each resource. No point pulling data more than once.
                           plainNotifications(notification.Resource) = notification
                        End Sub)

            If plainNotifications.Count > 0 Then
               ' Query for the changed messages
               GetChangedMessages(plainNotifications.Values)
            End If

            If notificationCollection.ValidationTokens IsNot Nothing AndAlso notificationCollection.ValidationTokens.Any() Then
               ' -> notificationCollection.ValidationTokens is not set at the customer
            End If

         Catch ex As Exception
            ' Still return a 202 so the service doesn't resend the notification.
         End Try
         Return Accepted()
      End Function

Код для создания подписки

         Subscription = graphApi.Client.Subscriptions.Request().AddAsync(New Subscription() With
            {
               .Resource = $"/communications/presences?$filter=id in ({String.Join(",", userIds.Select(Function(id) $"'{id}'"))})",
               .ChangeType = "updated",
               .NotificationUrl = $"{publicNotificationEndpoint}/Notification/{connectorid}/{Me.GraphApi.Link.Id}",
               .LifecycleNotificationUrl = $"{publicNotificationEndpoint}/LifecycleNotification/{connectorid}/{Me.GraphApi.Link.Id}",
               .ClientState = SecretClientState,
               .ExpirationDateTime = DateTime.UtcNow.Add(MAX_SUBSCRIPTION_LIFETIME),
               .EncryptionCertificate = Convert.ToBase64String(encryptionCertificate.Export(X509ContentType.Cert)),
               .EncryptionCertificateId = encryptionCertificate.Version.ToString(),
               .IncludeResourceData = True
            }).Result

person hypetsch    schedule 26.04.2021    source источник
comment
Просто чтобы изолировать проблему, вы можете попробовать воспроизвести проблему с помощью Graph Explorer или POSTMAN, чтобы увидеть, увидите ли вы другой результат.   -  person Dev    schedule 29.04.2021
comment
Привет @hypetsch, не могли бы вы поделиться фрагментом кода, который вы используете для получения токенов проверки.   -  person Jagadeesh-MSFT    schedule 04.05.2021
comment
@Jagadeesh-MSFT - по запросу я добавил (упрощенный) код выше, но, как уже упоминалось, validationTokens не являются частью содержимого JSON, которое мы получаем в уведомлении. JSON, который я добавил в вопрос, на самом деле представляет собой отформатированный/укороченный контент, захваченный с помощью Wireshark. В любом случае я отметил позицию, в которой свойство .validationTokens не установлено.   -  person hypetsch    schedule 05.05.2021
comment
Привет @hypetsch, ты все еще сталкиваешься с проблемой?   -  person Jagadeesh-MSFT    schedule 19.05.2021
comment
Тем временем мы реализовали обходной путь (и игнорируем токены проверки). Я попрошу наш отдел обслуживания связаться с клиентом и спросить, могут ли они попробовать это.   -  person hypetsch    schedule 19.05.2021
comment
@Jagadeesh-MSFT, мы получили отзыв от нашего клиента: он по-прежнему не работает без обходного пути (который игнорирует токены проверки)   -  person hypetsch    schedule 25.05.2021
comment
Привет @hypetsch, мы скоро сообщим вам.   -  person Jagadeesh-MSFT    schedule 25.05.2021
comment
Привет @hypetsch, наша команда отлаживает ваш код, ответ будет опубликован сегодня   -  person Jagadeesh-MSFT    schedule 11.06.2021
comment
@Jagadeesh-MSFT, клиент спросил, есть ли у вас новости. Обходной путь все еще существует, поэтому в настоящее время мы не можем подтвердить, что свойство validationTokens по-прежнему отсутствует. Если вам требуется дополнительная информация (например, данные, относящиеся к арендатору, фактически используемый URL-адрес уведомления, текущая трассировка сети...), сообщите нам об этом — мы можем спросить клиента, можно ли предоставить такую ​​информацию напрямую.   -  person hypetsch    schedule 01.07.2021


Ответы (1)


Я думаю, это то, что вы ищете, подписавшись на API присутствия с помощью API уведомлений об изменениях. Мы разработали образцы в csharp и node js, которые имеют возможность уведомлять пользователя об обновлении присутствия. Вы можете взглянуть на следующий образец github репозиторий кода graph-change-notification по вашему сценарию.

person Trinetra-MSFT    schedule 29.06.2021
comment
Спасибо за ответ, но проблема в нашем случае только в том, что в полученном уведомлении отсутствуют validationTokens (только у конкретного клиента, а у других работает нормально) - и как мы понимаем документы, они должны быть там в случае наличия ресурсов docs.microsoft .com/en-us/graph/api/resources/ - person hypetsch; 30.06.2021
comment
... полученные данные о присутствии в порядке (также и у этого клиента), поэтому наш обходной путь состоял в том, чтобы обрабатывать данные без предварительной проверки полученного запроса. - person hypetsch; 30.06.2021