サブスクリプションと変更通知の消失を減らす

変更通知の受信登録をしているアプリでは、サブスクリプションが削除され、変更通知が配信されない場合があります。 変更通知の継続的な配信を再開させるには、そのような消失を検出し、設定を復元するためのロジックをアプリで実装する必要があります。

特定のイベントが発生すると、サブスクリプションが削除されることがあります。これらのイベントには次のようなものがあります。

  • ユーザーのパスワードがリセットされた場合
  • ユーザーのデバイスが準拠しなくなった場合
  • ユーザーのアカウントが取り消された場合

このようなイベントが発生すると、Microsoft Graph は特殊なライフサイクル通知である subscriptionRemoved を送信します。

変更通知をアプリに配信できない場合、Microsoft Graph は missed という別のライフサイクル通知を送信します。

変更通知を受信登録してあるアプリでは、subscriptionRemovedmissed のシグナルを検出し、次のことを行う必要があります。

  • subscriptionRemoved ライフサイクル通知を受信すると、継続的な受信を維持できるよう、アプリでサブスクリプションが再作成されます。
  • missed ライフサイクル通知を受信した場合は、アプリでは Microsoft Graph を使用してリソース データが再同期されます。

ライフサイクル通知を受信するには、すでに変更通知を受信している既存の notificationUrl エンドポイントを使用するか、subscriptionRemovedmissed ライフサイクル通知を異なるエンドポイントで受信できるように別の lifecycleNotificationUrl を登録するかのいずれを行います。

ライフサイクル通知は、以下のリソースの種類で作成されたサブスクリプションをサポートしています。

  • Outlook [メッセージ][]
  • Outlook [イベント][]
  • Outlook 個人用[連絡先][]
  • Teams chatMessage

その他のリソースの種類については、サブスクリプションを作成するときにlifecycleNotificationUrl を引き続き提供することができ、リソースがそれを実装するたびにアプリケーションはライフサイクル通知を受け取ります。

サブスクリプションの作成

サブスクリプションを作成する際は、lifecycleNotificationUrl プロパティを使用して異なる通知エンドポイントを指定する必要があります。 エンドポイントを指定すると、現在および将来のすべてのタイプのライフサイクル通知がそのエンドポイントに配信されます。 それ以外の場合、subscriptionRemovedmissed ライフサイクル通知は配信されません。 このエンドポイントは、notificationUrl と同一にすることもできます。

サブスクリプション要求の例

POST https://graph.microsoft.com/v1.0/subscriptions
Content-Type: application/json

{
  "changeType": "created,updated",
  "notificationUrl": "https://webhook.azurewebsites.net/api/resourceNotifications",
  "lifecycleNotificationUrl": "https://webhook.azurewebsites.net/api/lifecycleNotifications",
  "resource": "/users/{id}/messages",
  "expirationDateTime": "2020-03-20T11:00:00.0000000Z",
  "clientState": "<secretClientState>"
}

重要

両方の通知 URL で同じホスト名 (FQDN) を使用します。

サブスクリプションの管理で説明されているように、両方のエンドポイントを検証する必要があります。  両エンドポイントに同じ URL を使用することを選択した場合は、検証要求が 2 通配信されるので、両方に応答します。

注: 既存のサブスクリプションを更新 (PATCH) して lifecycleNotificationUrl プロパティを追加することはできません。 そのような既存のサブスクリプションは削除し、新しいサブスクリプションを作成して lifecycleNotificationUrl プロパティを指定する必要があります。 lifecycleNotificationUrl プロパティが指定されていない既存のサブスクリプションは、subscriptionRemoved および missed 通知を受け取りません。

SubscriptionRemoved 通知に応答する

subscriptionRemoved ライフサイクル通知は、サブスクリプションが削除され、変更通知の受信を継続するにはサブスクリプションを再作成する必要があることを通知します。

有効期限が長いサブスクリプション(3 日)を作成すると、変更通知の notificationUrl への送信が開始されます。 ただし、リソース データへのアクセスの条件は時間の経過とともに変化する可能性があるので注意が必要です。 たとえば、アプリでユーザーの再認証が必要になるイベントがサービスで発生する場合があります。 そのような場合、フローは次のようになります。

  1. サービスは、Microsoft Graph からサブスクリプションを削除する必要があることを検出します。

    これらのイベントは、決まった頻度で発生するわけではありません。 イベントが頻繁に発生するリソースもあれば、ほとんど発生しないリソースもあります。

  2. Microsoft Graph は subscriptionRemoved ライフサイクル通知を lifecycleNotificationUrl (指定されている場合) に送信します。

  3. このライフサイクル通知には、同じリソースに対して新しいサブスクリプションを作成することにより応答できます。 これを行うには、有効なアクセス トークンを提示する必要があります。場合によっては、新しい有効なアクセス トークンを取得するために、アプリでユーザーを再認証する必要があります。

  4. 新しいサブスクリプションを正常に作成すると、変更通知の配信が再開されます。 作成に失敗した場合 (たとえば、アプリが有効なアクセス トークンを取得できなかった場合)、変更通知は送信されません。

  5. 新しいサブスクリプションを作成したら、喪失した変更を特定するためにリソース データを同期できます。

SubscriptionRemoved 通知の例

{
  "value": [
    {
      "subscriptionId":"<subscription_guid>",
      "subscriptionExpirationDateTime":"2019-03-20T11:00:00.0000000Z",
      "tenantId": "<tenant_guid>",
      "clientState":"<secretClientState>",
      "lifecycleEvent": "subscriptionRemoved"
    }
  ]
}

このタイプの通知にはいくつかの注意点があります。

  • "lifecycleEvent": "subscriptionRemoved" フィールドは、この通知はサブスクリプションの削除に関連したものであることを示します。 他の種類のライフサイクル通知が配信される可能性もあり、今後は新しい通知が導入される予定です。
  • ライフサイクル通知には特定のリソースに関する情報は含まれていません。通知はサブスクリプションの状態の変更に関するもので、リソースの変更とは関係がないためです。
  • 変更通知と同様に、ライフ サイクル通知はバッチ処理でき (value 配列内で)、それぞれの通知は異なる lifecycleEvent 値を持つことができます。 バッチ内の各ライフサイクル通知を適切に処理します。

: 変更通知が配信されたときに送信されるデータの詳細については、changeNotificationCollection を参照してください。

必要なアクション

  1. POST 呼び出しに 202 - Accepted で応答し、通知の受信を確認通知します。
  2. ライフサイクル通知の信頼性を検証します。
  3. 次の手順に進むために有効なアクセス トークンがアプリにあることを確認します。

注: いずれかの 認証ライブラリを使用している場合、その認証ライブラリは、有効なキャッシュされたトークンを再利用するか、ユーザーに再度サインイン (新しいパスワードで) するよう要求するなどして新しいトークンを取得することにより、トークンを処理します。 アクセスの状況の変化などの理由により呼び出し側がリソース データへのアクセス許可を失っている場合があるため、新しいトークンの取得が失敗する可能性があることに注意してください。

  1. こちらに記載されている標準的な手順に従って、新しいサブスクリプションを作成します。

注: システムが実行する承認チェックによりアプリまたはユーザーのリソースへのアクセスが拒否される可能性があるため、このアクションは失敗する可能性があります。 サブスクリプションを正常に再認証するには、アプリはユーザーから新しいアクセス トークンを取得する必要がある場合があります。 アクセス条件に変更があった場合などは、これらのアクションはいつでも再試行できます。 ライフサイクル通知が送信されてからアプリがサブスクリプションを正常に再作成するまでの間に発生したリソースの変更は、すべて失われます。 アプリは、それらの変更を独自に取得する必要があります。

  1. 新しいサブスクリプションを作成した後、このリソースに関する変更通知を受け取った最後の既知の時間以降の受信できなかったリソース データを同期します。 例: GET https://graph.microsoft.com/v1.0/users/{id}/messages?$filter=createdDateTime+ge+{LastTimeNotificationWasReceived}

受信できなかった通知への応答

これらのシグナルは、配信されなかった可能性がある変更通知があることを知らせます。 これらのシグナルを無視するか対処するかを決めます。

通知の例

{
  "value": [
    {
      "subscriptionId":"<subscription_guid>",
      "subscriptionExpirationDateTime":"2019-03-20T11:00:00.0000000Z",
      "tenantId": "<tenant_guid>",
      "clientState":"<secretClientState>",
      "lifecycleEvent": "missed"
    }
  ]
}

このタイプの通知にはいくつかの注意点があります。

  • この "lifecycleEvent": "missed" フィールドは、この変更通知が受信出来なかった通知に関するシグナルであることを示します。 他の種類のライフサイクル通知が配信される可能性もあり、今後は新しい通知が導入される予定です。
  • ライフサイクル通知には特定のリソースに関する情報は含まれていません。通知はサブスクリプションの状態の変更に関するもので、リソースの変更とは関係がないためです。
  • リソース通知と同様に、ライフサイクル通知はバッチ処理でき (value 配列内で)、それぞれの通知は異なる lifecycleEvent 値を持つことができます。 バッチ内の各ライフサイクル通知を適切に処理します。

: 変更通知が配信されたときに送信されるデータの詳細については、changeNotificationCollection を参照してください。

必要なアクション

  1. POST 呼び出しに 202 - Accepted で応答し、通知の受信を確認通知します。
    • シグナルを無視する場合は、特に操作は必要ありません。無視しない場合は:
  2. ライフサイクル通知の信頼性を検証します。
  3. 通知として配信されなかった変更を特定するために、すべてのデータを対象にリソースの再同期を実行します。

reauthorizationRequire 通知に応答する

reauthorizationRequired のライフサイクル通知を受信したときに、データ フローを維持するには、サブスクリプションを再認証する必要があります。

リソースでサポートされている最大サブスクリプションの最大有効期間に応じて、有効期間の長いサブスクリプションを作成できます。これにより、変更通知を notificationUrl に送信できます。 サブスクリプションの作成後にアクセス条件が変更された場合、または近い将来に通知フローが中断される可能性があることを Microsoft Graph が検出した場合、Microsoft Graph は、リソースのデータにまだアクセスできることを証明するためにサブスクリプションの再認証を要求する場合があります。 データへのアクセスに影響を与える可能性がある条件の例を次に示します。

  • テナント管理者は、アプリに付与されているリソースの読み取りアクセス許可を取り消すことができます。
  • 対話型のシナリオでは、アプリに認証トークンを提供しているユーザーに対して、場所、デバイス状態、またはリスク評価などのさまざまな要素に基づいた動的なポリシーが適用される場合があります。 たとえば、ユーザーの物理的な場所が変更された場合、ユーザーはデータにアクセスできなくなり、アプリはサブスクリプションを再承認できなくなります。 アクセスを制御する動的ポリシーの詳細については、「Azure AD 条件付きアクセス ポリシー」を参照してください。
  • アクセス トークンの有効期限が切れます。 これは、リソース データを含む通知にのみ適用されます。
  • サブスクリプションの有効期限は、更新する前に切れます。

これらの条件のいずれかが満たされる前に、Microsoft Graph は lifecycleNotificationUrl 認可チャレンジを送信します。 これらの通知の間隔を次に示します。

    //The following code is for illustrative purposes only
    var TokenTimeToExpirationInMinutes=(TokenExpirationTime-CurrentTime)/4;
    if((TokenTimeToExpirationInMinutes)<=180 && TokenTimeToExpirationInMinutes>60){
        //Microsoft Graph will send reauthorizationRequired notification
        TokenTimeToExpirationInMinutes=TokenTimeToExpirationInMinutes/2;
    }
    elseif(TokenTimeToExpirationInMinutes<60 && TokenTimeToExpirationInMinutes>=0){
            //Microsoft Graph will send reauthorizationRequired notification every 15 mins
            TokenTimeToExpirationInMinutes=TokenTimeToExpirationInMinutes-15;
    }else{
      //Microsoft Graph will stop sending reauthorizationRequired notifications
    }

アクティブな、有効期限が切れていないサブスクリプションの承認チャレンジのフローは、次のようになります。

  1. Microsoft Graph によりサブスクリプションの再認証が要求されます。

    この理由はリソースによって異なり、時間の経過と共に変化することがあります。 再認証イベントは、その原因にかかわらず応答する必要があります。

  2. Microsoft Graph により承認チャレンジ通知が lifecycleNotificationUrl に送信されます。

    応答するまでの猶予をユーザーに与えるために、変更通知のフローがしばらく継続する場合があります。 ただし、ユーザーが必要なアクションを実行するまで、最終的には変更通知の配信は一時停止されます。

  3. このライフサイクル通知には、次の 2 つの方法のいずれかで応答します:

    • サブスクリプションを再認証する。 これによりサブスクリプションの有効期限が延長されることはありません。
    • サブスクリプションを更新する。 これにより、有効期限が再認証され、延長されます。

    注: いずれのアクションでも、新しいサブスクリプションを作成する場合や有効期限の前にサブスクリプションを更新する場合と同様に、有効な認証トークンを提示する必要があります。

  4. サブスクリプションを正常に再認証または更新した場合、変更通知は継続されます。 それ以外の場合、変更通知は一時停止されたままになります。 Microsoft Graph では、通知が一時停止されてから 4 時間後に削除されることに注意してください。

reauthorizationRequired 通知ペイロードの例

{
  "value": [
    {
      "lifecycleEvent": "reauthorizationRequired",
      "subscriptionId": "e3898f08-5cd0-4a6a-80fc-6addbfb73b7b",
      "subscriptionExpirationDateTime": "2019-09-18T00:52:45.9696658+00:00",
      "clientState": "{secret client state}",
      "tenantId": "84bd8158-6d4d-4958-8b9f-9d6445542f95"
    }
  ]
}

このタイプの通知には次のようないくつかの注意点があります。

  • "lifecycleEvent": "reauthorizationRequired" フィールドにより、この通知は承認チャレンジとして指定されています。 missedsubscriptionRemoved lifecycleEvent 通知もサポートされています。
  • ライフサイクル通知には特定のリソースに関する情報は含まれていません。通知はサブスクリプションの状態の変更に関するもので、リソースの変更とは関係がないためです。

: 変更通知が配信されたときに送信されるデータの詳細については、changeNotificationCollection を参照してください。

必要なアクション

  1. POST 呼び出しに 202 - Accepted で応答し、通知の受信を確認通知します。
  2. ライフサイクル通知の信頼性を検証します。
  3. 次の手順に進むために有効なアクセス トークンがアプリにあることを確認します。

注: いずれかの 認証ライブラリを使用している場合、その認証ライブラリは、有効なキャッシュされたトークンを再利用するか、ユーザーに再度サインイン (新しいパスワードで) するよう要求するなどして新しいトークンを取得することにより、トークンを処理します。 アクセスの状況の変化などの理由により呼び出し側がリソース データへのアクセス許可を失っている場合があるため、新しいトークンの取得が失敗する可能性があることに注意してください。

  1. 次の 2 つの API のいずれかを呼び出します。 API 呼び出しが成功した場合、変更通知のフローが再開されます。

    • /reauthorize アクションを呼び出し、有効期限を延長せずにサブスクリプションを再認証します。

      POST  https://graph.microsoft.com/beta/subscriptions/{id}/reauthorize
      Content-type: application/json
      
    • サブスクリプションの再認証と更新を同時に行うための定期的な更新アクションを実行します。

      PATCH https://graph.microsoft.com/beta/subscriptions/{id}
      Content-Type: application/json
      
      {
         "expirationDateTime": "2019-09-21T11:00:00.0000000Z"
      }
      

      システムが実行する認証チェックによりアプリまたはユーザーのリソースへのアクセスが拒否される可能性があるため、更新が失敗する場合があります。 サブスクリプションを正常に再認証するには、アプリはユーザーから新しいアクセス トークンを取得する必要がある場合があります。

      これらのアクションはいつでも再試行できます。アクセスの条件に変更があった場合は、成功する場合があります。 ライフサイクル通知が送信された時点からサブスクリプションがアプリで正常に再作成された時点までの間に発生したリソースの変更に関する通知は、失われる場合があります。 このような場合、アプリはこれらの変更を個別に取得する必要があります。

追加情報

承認チャレンジについては、次の詳細情報をご確認ください。

  • 承認チャレンジにより、リソース変更サブスクリプションを期限切れになる前に更新する必要がなくなるわけではありません。

    承認チャレンジを受信した際はサブスクリプションを更新することもできますが、Microsoft Graph ではすべてのサブスクリプションに対してチャレンジするとは限りません。 たとえば、アクティビティが何もなく、配信保留中の変更通知がないサブスクリプションの場合、アプリに対して再承認チャレンジが送信されない場合があります。 サブスクリプションの更新は、有効期限が切れる前に行うようにします。

  • 承認チャレンジの頻度は、変更される場合があります。

    そのため、承認チャレンジの頻度については、決めてかからないようにします。 これらのライフサイクル通知では、アクションを実行すべきタイミングが知らされるため、どのサブスクリプションで再承認が必要なのかを追跡する手間が省けます。 承認チャレンジは、数分おきにすべてのサブスクリプションで発生する場合も、ごくたまに一部のサブスクリプションでのみ発生する場合もあるため、対応できるようにしておきます。

コードが今後もライフサイクル通知を処理できるようにする

Microsoft Graph では今後、より多くの種類のサブスクリプション ライフサイクル通知が追加される予定です。 これらの通知はこれまでと同じエンドポイント (lifecycleNotificationUrl) にポストされますが、通知の lifecycleEvent の値が変更され、通知を発行する目的のシナリオに固有の、これまでとはわずかに異なるスキーマとプロパティが含まれる可能性があります。

Microsoft Graph に新しい種類のライフ サイクル通知が導入された場合でもコードが正常に動作するよう、コードは将来を見込んだ方法で実装する必要があります。次のようなアプローチをお勧めします。

  1. lifecycleEvent プロパティを使用して、サポートするイベントとして各ライフサイクル通知を明示的に識別します。 たとえば、特定のイベントを特定するために "lifecycleEvent": "subscriptionRemoved" プロパティを探し、それを処理します。

  2. 新しいシナリオのライフサイクル通知の発表を見守ります。今後より多くの種類のライフサイクル通知が導入される可能性があります。

  3. アプリでは、アプリが認識しないすべてのライフサイクル通知を無視するようにしますが、今後の参考にするために記録を残します。

  4. 必要と判断する場合は、新しいライフサイクル通知に関連する資料を確認し、適切なサポートを実装します。

関連項目