次の方法で共有


Microsoft ID プラットフォームのアクセス トークン

アクセス トークンは、認証済みのユーザーに代わって特定のリソースへのアクセスを許可する、認可用に設計されたセキュリティ トークンの一種です。 アクセス トークンに含まれる情報によって、ユーザーが特定のリソースにアクセスする権限があるかどうかが決定されます。これは、建物内の特定のドアを開ける鍵のような役割を果たします。 トークンを構成するこれらの個々の情報は、クレームと呼ばれます。 そのため、これらは機密性の高い資格情報であり、正しく処理されない場合はセキュリティ リスクを引き起こす可能性があります。 アクセス トークンは、認証の証明として機能する ID トークンとは異なります。

アクセス トークンにより、クライアントは保護された Web API を安全に呼び出すことができます。 クライアント アプリケーションはアクセス トークンを受け取って使用できますが、不透明な文字列として扱う必要があります。 クライアント アプリケーションは、アクセス トークンの検証を試みるべきではありません。 リソース サーバーは、アクセス トークンを認可の証明として受け入れる前に検証する必要があります。 トークンの内容は API のみを対象としているため、アクセス トークンは不透明な文字列として扱う必要があります。 検証とデバッグ "のみ" を目的として、開発者は jwt.ms などのサイトを使用して JWT をデコードできます。 Microsoft API が受信するトークンは、常にデコードできる JWT であるとは限りません。

クライアントは、アクセス トークンと共に返されるトークン応答データを使用して、その内容の詳細を確認する必要があります。 クライアントがアクセス トークンを要求すると、Microsoft ID プラットフォームからは、アプリケーションで使用されるそのアクセス トークンに関する何らかのメタデータも返されます。 この情報には、アクセス トークンの有効期限や、それが有効なスコープが含まれます。 このデータを使用すると、アプリケーションはアクセス トークン自体を解析しなくても、そのアクセス トークンのインテリジェントなキャッシュを実行できます。 この記事では、形式、所有権、有効期間、API がアクセス トークン内のクレームを検証して使用する方法など、アクセス トークンに関する重要な情報について説明します。

Note

このページのすべてのドキュメントは、特に記載がある場合を除き、登録された API に対して発行されるトークンにのみ適用されます。 Microsoft が所有する API に対して発行されるトークンには適用されません。また、それらのトークンを使用して、Microsoft ID プラットフォームが、登録された API に対してトークンを発行する方法を検証することもできません。

トークンの形式

Microsoft ID プラットフォームで使用できるアクセス トークンには、v1.0 と v2.0 の 2 つのバージョンがあります。 これらのバージョンでは、トークン内の要求を決定し、Web API がトークンの内容を制御できるようにします。

Web API では、登録時に次のいずれかのバージョンが既定として選択されます。

  • Microsoft Entra 専用アプリケーションの場合は v1.0。 次の例は v1.0 トークンを示しています (キーは変更され、個人情報は削除されており、トークンの検証はできません)。

    eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Imk2bEdrM0ZaenhSY1ViMkMzbkVRN3N5SEpsWSIsImtpZCI6Imk2bEdrM0ZaenhSY1ViMkMzbkVRN3N5SEpsWSJ9.eyJhdWQiOiJlZjFkYTlkNC1mZjc3LTRjM2UtYTAwNS04NDBjM2Y4MzA3NDUiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9mYTE1ZDY5Mi1lOWM3LTQ0NjAtYTc0My0yOWYyOTUyMjIyOS8iLCJpYXQiOjE1MzcyMzMxMDYsIm5iZiI6MTUzNzIzMzEwNiwiZXhwIjoxNTM3MjM3MDA2LCJhY3IiOiIxIiwiYWlvIjoiQVhRQWkvOElBQUFBRm0rRS9RVEcrZ0ZuVnhMaldkdzhLKzYxQUdyU091TU1GNmViYU1qN1hPM0libUQzZkdtck95RCtOdlp5R24yVmFUL2tES1h3NE1JaHJnR1ZxNkJuOHdMWG9UMUxrSVorRnpRVmtKUFBMUU9WNEtjWHFTbENWUERTL0RpQ0RnRTIyMlRJbU12V05hRU1hVU9Uc0lHdlRRPT0iLCJhbXIiOlsid2lhIl0sImFwcGlkIjoiNzVkYmU3N2YtMTBhMy00ZTU5LTg1ZmQtOGMxMjc1NDRmMTdjIiwiYXBwaWRhY3IiOiIwIiwiZW1haWwiOiJBYmVMaUBtaWNyb3NvZnQuY29tIiwiZmFtaWx5X25hbWUiOiJMaW5jb2xuIiwiZ2l2ZW5fbmFtZSI6IkFiZSAoTVNGVCkiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMjIyNDcvIiwiaXBhZGRyIjoiMjIyLjIyMi4yMjIuMjIiLCJuYW1lIjoiYWJlbGkiLCJvaWQiOiIwMjIyM2I2Yi1hYTFkLTQyZDQtOWVjMC0xYjJiYjkxOTQ0MzgiLCJyaCI6IkkiLCJzY3AiOiJ1c2VyX2ltcGVyc29uYXRpb24iLCJzdWIiOiJsM19yb0lTUVUyMjJiVUxTOXlpMmswWHBxcE9pTXo1SDNaQUNvMUdlWEEiLCJ0aWQiOiJmYTE1ZDY5Mi1lOWM3LTQ0NjAtYTc0My0yOWYyOTU2ZmQ0MjkiLCJ1bmlxdWVfbmFtZSI6ImFiZWxpQG1pY3Jvc29mdC5jb20iLCJ1dGkiOiJGVnNHeFlYSTMwLVR1aWt1dVVvRkFBIiwidmVyIjoiMS4wIn0.D3H6pMUtQnoJAGq6AHd
    
  • コンシューマー アカウントをサポートするアプリケーションの場合、v2.0。 次の例は、v2.0 トークンを示しています (キーは変更され、個人情報は削除されており、トークンの検証はできません)。

    eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Imk2bEdrM0ZaenhSY1ViMkMzbkVRN3N5SEpsWSJ9.eyJhdWQiOiI2ZTc0MTcyYi1iZTU2LTQ4NDMtOWZmNC1lNjZhMzliYjEyZTMiLCJpc3MiOiJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vNzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3L3YyLjAiLCJpYXQiOjE1MzcyMzEwNDgsIm5iZiI6MTUzNzIzMTA0OCwiZXhwIjoxNTM3MjM0OTQ4LCJhaW8iOiJBWFFBaS84SUFBQUF0QWFaTG8zQ2hNaWY2S09udHRSQjdlQnE0L0RjY1F6amNKR3hQWXkvQzNqRGFOR3hYZDZ3TklJVkdSZ2hOUm53SjFsT2NBbk5aY2p2a295ckZ4Q3R0djMzMTQwUmlvT0ZKNGJDQ0dWdW9DYWcxdU9UVDIyMjIyZ0h3TFBZUS91Zjc5UVgrMEtJaWpkcm1wNjlSY3R6bVE9PSIsImF6cCI6IjZlNzQxNzJiLWJlNTYtNDg0My05ZmY0LWU2NmEzOWJiMTJlMyIsImF6cGFjciI6IjAiLCJuYW1lIjoiQWJlIExpbmNvbG4iLCJvaWQiOiI2OTAyMjJiZS1mZjFhLTRkNTYtYWJkMS03ZTRmN2QzOGU0NzQiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhYmVsaUBtaWNyb3NvZnQuY29tIiwicmgiOiJJIiwic2NwIjoiYWNjZXNzX2FzX3VzZXIiLCJzdWIiOiJIS1pwZmFIeVdhZGVPb3VZbGl0anJJLUtmZlRtMjIyWDVyclYzeERxZktRIiwidGlkIjoiNzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3IiwidXRpIjoiZnFpQnFYTFBqMGVRYTgyUy1JWUZBQSIsInZlciI6IjIuMCJ9.pj4N-w_3Us9DrBLfpCt
    

アプリ マニフェストaccessTokenAcceptedVersion 設定に適切な値を指定して、アプリケーションのバージョンを設定します。 null および 1 の値では v1.0 トークンになり、2 の値では v2.0 トークンになります。

トークンの所有権

アクセス トークン要求には 2 つのパーティが関与します。トークンを要求するクライアントと、トークンを受け入れるリソース (Web API) です。 トークンの対象となるリソース (その対象ユーザー) は、トークンの aud 要求で定義されます。 クライアントはトークンを使用しますが、それを理解したり解析しようとしたりすることはできません。 リソースはトークンを受け入れます。

Microsoft ID プラットフォームでは、任意のバージョンのエンドポイントからの任意のトークン バージョンの発行がサポートされています。 たとえば、accessTokenAcceptedVersion の値が 2 の場合、v1.0 エンドポイントを呼び出してそのリソースのトークンを取得するクライアントは、v2.0 アクセス トークンを受け取ります。

リソースは、aud 要求を使用するトークンを常に所有し、トークンの詳細を変更できる唯一のアプリケーションになります。

トークンの有効期間

アクセス トークンの既定の有効期間は、可変です。 発行されると、Microsoft ID プラットフォームはアクセス トークンの既定の有効期間として、60 分から 90 分 (平均で 75 分) の範囲でランダムな値を割り当てます。 このバリエーションによって、期間内にアクセス トークンの要求が分散してサービスの回復性が向上します。これで、Microsoft Entra ID へのトラフィックが 1 時間ごとに急増することを防止します。

条件付きアクセスを使用しないテナントでは、Microsoft Teams や Microsoft 365 などのクライアントに対して、既定のアクセス トークンの有効期間は 2 時間です。

アクセス トークンの有効期間を調整して、クライアント アプリケーションがアプリケーション セッションを期限切れにする頻度と、ユーザーに再認証 (サイレントまたは対話形式) を要求する頻度を制御できます。 既定のアクセス トークンの有効期間のバリエーションをオーバーライドするには、構成可能なトークンの有効期間 (CTL) を使用します。

既定のトークンの有効期間のバリエーションを、継続的アクセス評価 (CAE) が有効な組織に適用します。 組織が CTL ポリシーを使用している場合でも、既定のトークンの有効期間のバリエーションを適用します。 有効期間が長いトークンの既定のトークンの有効期間の範囲は、20 時間から 28 時間です。 アクセス トークンの有効期限が切れると、クライアントは更新トークンを使用して新しい更新トークンとアクセス トークンを取得する必要があります。

条件付きアクセスのサインイン頻度 (SIF) を使用してサインインの頻度を適用する組織は、既定のアクセス トークンの有効期間のバリエーションをオーバーライドすることはできません。 組織が SIF を使用する場合、クライアントの資格情報プロンプトの間隔は、トークンの有効期間 (60 分から 90 分の範囲) に、サインイン頻度の間隔を加算したものになります。

既定のトークンの有効期間のバリエーションがサインイン頻度とどのように連動するかの例を次に示します。 たとえば、組織で 1 時間ごとにサインイン頻度が発生するように設定します。 トークンの有効期間のバリエーションにより、トークンの有効期間の範囲が 60 分から 90 分の場合、実際のサインイン間隔は 1 時間から 2.5 時間の間で発生します。

有効期間が 1 時間のトークンを持つユーザーが、59 分の時点で対話型サインインを実行する場合、そのサインインは SIF しきい値を下回るため、資格情報のプロンプトは表示されません。 新しいトークンの有効期間が 90 分の場合、次の 1 時間半の間、ユーザーに資格情報プロンプトは表示されません。 サイレント更新を実行しようとすると、セッションの長さの合計が サインイン頻度設定の 1 時間を超えたため、Microsoft Entra ID は資格情報プロンプトを要求します。 この例では、SIF 間隔とトークンの有効期間のバリエーションが原因で、資格情報プロンプトの時間差は 2.5 時間になります。

トークンを検証する

すべてのアプリケーションでトークンを検証する必要はありません。 アプリケーションでトークンを検証する必要があるのは、特定のシナリオのみです。

  • Web API は、クライアントから自身に送信されたアクセス トークンを検証する必要があります。 AppId URI の 1 つが aud クレームとして含まれるトークンのみを受け入れる必要があります。
  • Web アプリは、ユーザーのデータへのアクセスを許可する、またはセッションを確立する前に、ハイブリッド フローでユーザーのブラウザーを使用して自身に送信された ID トークンを検証する必要があります。

前述のシナリオが該当しない場合は、トークンを検証する必要はありません。 ネイティブ、デスクトップ、またはシングルページ アプリケーションのようなパブリック クライアントでは、SSL 保護で ID トークンの有効性が保証される IDP とアプリケーションが直接通信するため、ID トークンを検証してもメリットはありません。 アクセス トークンの検証は Web API での検証を目的としているため、クライアントでアクセス トークンを検証する必要はありません。

API と Web アプリケーションは、アプリケーションに一致する aud 要求を含むトークンのみを検証する必要があります。 その他のリソースには、カスタム トークン検証規則がある場合があります。 たとえば、Microsoft Graph のトークンは独自の形式であるため、これらの規則に従って検証することはできません。 別のリソースを対象とするトークンを検証して受け入れることは、混乱した使節 (Confused Deputy) の問題にたとえることができます。

アプリケーションで ID トークンまたはアクセス トークンを検証する必要がある場合は、最初に OpenID 探索ドキュメントの値と突き合わせてトークンの署名と発行者を検証する必要があります。

Microsoft Entra ミドルウェアにはアクセス トークンを検証するための機能が組み込まれており、適切な言語のサンプルを参照できます。 JWT の検証に使用できるサードパーティのオープン ソース ライブラリもいくつか存在します。 認証ライブラリとコード サンプルの詳細については、認証ライブラリに関する記事を参照してください。 Web アプリまたは Web API が ASP.NET または ASP.NET Core で実行されている場合は、検証に対処する Microsoft.Identity.Web を使います。

v1.0 トークンと v2.0 トークン

  • Web アプリ/API が v1.0 トークン (ver クレーム = "1.0") を検証している場合、Web API 用に構成された機関が v2.0 機関だとしても、v1.0 エンドポイント (https://login.microsoftonline.com/{example-tenant-id}/.well-known/openid-configuration) から OpenID Connect メタデータ ドキュメントを読み取る必要があります。
  • Web アプリ/API が v2.0 トークン (ver クレーム = "2.0") を検証している場合、Web API 用に構成された機関が v1.0 機関だとしても、v2.0 エンドポイント (https://login.microsoftonline.com/{example-tenant-id}/v2.0/.well-known/openid-configuration) から OpenID Connect メタデータ ドキュメントを読み取る必要があります。

次の例では、アプリケーションが v2.0 アクセス トークンを検証していることを前提としています (したがって、v2.0 バージョンの OIDC メタデータ ドキュメントとキーを参照します)。 v1.0 トークンを検証する場合は、URL の "/v2.0" を削除してください。

発行者を検証する

OpenID Connect Core には "発行者識別子 [...] は iss (発行者) クレームの値と完全に一致する必要があります" と表示されます。テナント固有のメタデータ エンドポイント (https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0/.well-known/openid-configurationhttps://login.microsoftonline.com/contoso.onmicrosoft.com/v2.0/.well-known/openid-configuration など) を使うアプリケーションの場合は、必要なものはこれだけです。

Microsoft Entra ID には、https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration で利用できるドキュメントのテナントに依存しないバージョンが与えられます。 このエンドポイントは、発行者の値 https://login.microsoftonline.com/{tenantid}/v2.0 を返します。 アプリケーションでは、このテナントに依存しないエンドポイントを使って、次の変更を加えてすべてのテナントからのトークンを検証できます。

  1. トークン内の発行者クレームがメタデータの発行者の値と正確に一致することを想定するのではなく、アプリケーションは発行者メタデータの {tenantid} 値を現在の要求のターゲットであるテナント ID に置き換えて、完全一致をチェックする必要があります。

  2. アプリケーションでは、キーのスコープを制限するために、キー エンドポイントから返される issuer プロパティを使う必要があります。

    • https://login.microsoftonline.com/{tenantid}/v2.0 のような発行者の値を持つキーは、一致するトークン発行者と共に使用できます。
    • https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0 のような発行者の値を持つキーは、完全一致でのみ使う必要があります。

    Microsoft Entra テナントに依存しないキー エンドポイント (https://login.microsoftonline.com/common/discovery/v2.0/keys) は、次のようなドキュメントを返します。

    {
      "keys":[
        {"kty":"RSA","use":"sig","kid":"A1bC2dE3fH4iJ5kL6mN7oP8qR9sT0u","x5t":"A1bC2dE3fH4iJ5kL6mN7oP8qR9sT0u","n":"spv...","e":"AQAB","x5c":["MIID..."],"issuer":"https://login.microsoftonline.com/{tenantid}/v2.0"},
        {"kty":"RSA","use":"sig","kid":"C2dE3fH4iJ5kL6mN7oP8qR9sT0uV1w","x5t":"C2dE3fH4iJ5kL6mN7oP8qR9sT0uV1w","n":"wEM...","e":"AQAB","x5c":["MIID..."],"issuer":"https://login.microsoftonline.com/{tenantid}/v2.0"},
        {"kty":"RSA","use":"sig","kid":"E3fH4iJ5kL6mN7oP8qR9sT0uV1wX2y","x5t":"E3fH4iJ5kL6mN7oP8qR9sT0uV1wX2y","n":"rv0...","e":"AQAB","x5c":["MIID..."],"issuer":"https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0"}
      ]
    }
    
  3. 標準の発行者クレームではなく、信頼境界として Microsoft Entra の tenantid (tid) クレームを使用するアプリケーションでは、テナント ID クレームが GUID であり、発行者とtenantid が一致していることを確認する必要があります。

多くのテナントからのトークンを受け入れるアプリケーションの場合、テナントに依存しないメタデータを使う方が効率的です。

Note

Microsoft Entra のテナントに依存しないメタデータでは、標準の OpenID Connect の場合と同様に、クレームはテナント内で解釈される必要があります。クレームは発行者内で解釈されます。 つまり、{"sub":"ABC123","iss":"https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0","tid":"aaaabbbb-0000-cccc-1111-dddd2222eeee"}{"sub":"ABC123","iss":"https://login.microsoftonline.com/bbbbcccc-1111-dddd-2222-eeee3333ffff/v2.0","tid":"bbbbcccc-1111-dddd-2222-eeee3333ffff"} は、sub は同じですが、sub のようなクレームは発行者/テナントのコンテキスト内で解釈されるため、異なるユーザーを記述しています。

署名を検証

JWT には 3 つのセグメントがあり、. 文字で区切られています。 1 番目のセグメントはヘッダー、2 番目は本文、3 番目は署名です。 署名セグメントを使用して、トークンの信頼性を評価します。

Microsoft Entra ID によって発行されるトークンは、RS256 など、業界標準の非対称暗号化アルゴリズムを使用して署名されます。 JWT のヘッダーには、トークンの署名に使用されたキーと暗号方法に関する情報が含まれます。

{
  "typ": "JWT",
  "alg": "RS256",
  "x5t": "H4iJ5kL6mN7oP8qR9sT0uV1wX2yZ3a",
  "kid": "H4iJ5kL6mN7oP8qR9sT0uV1wX2yZ3a"
}

alg 要求はトークンの署名に使用されたアルゴリズムを示し、kid 要求はトークンの検証に使用された特定の公開キーを示します。

いつでも、Microsoft Entra ID は公開/秘密キー ペアの特定セットのいずれかを使用して、ID トークンに署名できます。 Microsoft Entra ID は定期的に使用可能なキー セットをローテーションするため、このキー変更を自動的に処理するようにアプリケーションを作成します。 Microsoft Entra ID によって使用される公開キーの更新を確認する適切な頻度は、24 時間間隔です。

署名の検証に必要な署名キー データは、次の場所にある OpenID Connect メタデータのドキュメントを使用して入手します。

https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration

ヒント

ブラウザーで URL を試します

次の情報では、メタデータ ドキュメントについて説明します。

  • OpenID Connect 認証を実行するために必要なさまざまなエンドポイントの場所などの、いくつかの有効な情報を含む JSON オブジェクトです。
  • jwks_uri が含まれています。これは、トークンの署名に使用される秘密キーに対応する公開キーのセットの場所を示すものです。 jwks_uri にある JSON Web キー (JWK) には、特定の時点で使用されているすべての公開キー情報が含まれます。 「RFC 7517」では JWK 形式が記述されています。 アプリケーションには、JWT ヘッダーの kid 要求を使用し、このドキュメントから、特定のトークンの署名に使用された秘密キーに対応する公開キーを選択できます。 その後、正しい公開キーと指定されたアルゴリズムを使用して、署名の検証を実行できます。

注意

kid 要求を使用してトークンを検証します。 v1.0 トークンには x5tkid の両方の要求が含まれますが、v2.0 トークンには kid 要求のみ含まれます。

署名の検証を実行する方法については、このドキュメントでは説明していません。 必要に応じて、署名の検証に役立つオープン ソース ライブラリが多数存在します。 ただし、Microsoft ID プラットフォームには、標準に対する 1 つのトークン署名拡張であるカスタム署名キーがあります。

要求のマッピング 機能を使用した結果としてアプリケーションにカスタム署名キーがある場合は、アプリケーション ID を含む appid クエリ パラメーターを追加します。 検証には、アプリケーションの署名キー情報を指す jwks_uri を使用します。 例: https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration?appid=00001111-aaaa-2222-bbbb-3333cccc4444 には、https://login.microsoftonline.com/{tenant}/discovery/keys?appid=00001111-aaaa-2222-bbbb-3333cccc4444jwks_uri が含まれます。

発行者を検証する

ID トークンを検証する Web アプリ、およびアクセス トークンを検証する Web API は、トークンの発行者 (iss クレーム) を次に対して検証する必要があります。

  1. アプリケーション構成 (機関) に関連付けられている OpenID connect メタデータ ドキュメントから取得できる発行者。 検証対象のメタデータ ドキュメントは、次の項目に応じて異なります。
    • トークンのバージョン
    • アプリケーションでサポートされているアカウント。
  2. トークンのテナント ID (tid クレーム)。
  3. 署名キーの発行者。

シングル テナント アプリケーション

OpenID Connect Core には "発行者識別子 [...] は iss (発行者) クレームの値と完全に一致する必要があります" と表示されます。https://login.microsoftonline.com/{example-tenant-id}/v2.0/.well-known/openid-configurationhttps://login.microsoftonline.com/contoso.onmicrosoft.com/v2.0/.well-known/openid-configuration など、テナント固有のメタデータ エンドポイントを使うアプリケーションの場合。

シングル テナント アプリケーションは、次をサポートするアプリケーションです。

  • 1 つの組織ディレクトリ内のアカウント (example-tenant-id のみ): https://login.microsoftonline.com/{example-tenant-id}
  • 個人用 Microsoft アカウントのみ: https://login.microsoftonline.com/consumers (consumers はテナント 9188040d-6c67-4c5b-b112-36a304b66dad のニックネーム)

マルチテナント アプリケーション

Microsoft Entra ID では、マルチテナント アプリケーションもサポートされています。 これらのアプリケーションでは、次がサポートされます。

  • 任意の組織ディレクトリ内のアカウント (任意の Microsoft Entra ディレクトリ): https://login.microsoftonline.com/organizations
  • 任意の組織ディレクトリ (任意の Microsoft Entra ディレクトリ) 内のアカウント、および個人用 Microsoft アカウント (Skype、Xbox など): https://login.microsoftonline.com/common

これらのアプリケーションの場合、Microsoft Entra ID では、https://login.microsoftonline.com/common/v2.0/.well-known/openid-configurationhttps://login.microsoftonline.com/organizations/v2.0/.well-known/openid-configuration のそれぞれで、テナントに依存しない OIDC ドキュメントのバージョンが公開されます。 これらのエンドポイントは発行者の値を返します。これは、tenantid: https://login.microsoftonline.com/{tenantid}/v2.0 でパラメーター化されたテンプレートです。 アプリケーションでは、このテナントに依存しないエンドポイントを使用して、以下の要件を満たすことですべてのテナントからのトークンを検証できます。

  • 署名キーの発行者を検証する
  • トークン内の発行者クレームがメタデータの発行者の値と正確に一致することを想定するのではなく、アプリケーションは発行者メタデータの {tenantid} 値を現在の要求のターゲットであるテナント ID に置き換えて、完全一致 (トークンの tid クレーム) をチェックする必要があります。
  • tid クレームが GUID であり、iss クレームが https://login.microsoftonline.com/{tid}/v2.0 の形式であることを検証します。ここで、{tid}tid クレームと完全に同一です。 この検証により、テナントが発行者に関連付けられ、さらに署名キーのスコープに関連付けられることで、信頼チェーンが作成されます。
  • クレームのサブジェクトに関連付けられているデータを特定する際に、必ず tid クレームを使用します。 つまり、tid クレームは、ユーザー データへのアクセスに使用されるキーの一部である必要があります。

署名キーの発行者を検証する

トークンの発行者に加えて、テナントに依存しないメタデータ v2.0 を使用するアプリケーションは、署名キーの発行者を検証する必要があります。

キー ドキュメントおよび署名キー発行者

前述のように、OpenID Connect ドキュメントから、アプリケーションはトークンの署名に使用されるキーにアクセスします。 OpenIdConnect ドキュメントの jwks_uri プロパティで公開されている URL にアクセスすることで、対応するキー ドキュメントを取得します。

 "jwks_uri": "https://login.microsoftonline.com/{example-tenant-id}/discovery/v2.0/keys",

{example-tenant-id} の値は GUID、ドメイン名、または commonorganizationsconsumers に置き換えることができます

Azure AD v2.0 によって公開される keys ドキュメントには、この署名キーを使用する発行者がキーごとに含まれています。 たとえば、テナントに依存しない "common" キー エンドポイント https://login.microsoftonline.com/common/discovery/v2.0/keys は次のようなドキュメントを返します。

{
  "keys":[
    {"kty":"RSA","use":"sig","kid":"A1bC2dE3fH4iJ5kL6mN7oP8qR9sT0u","x5t":"A1bC2dE3fH4iJ5kL6mN7oP8qR9sT0u","n":"spv...","e":"AQAB","x5c":["MIID..."],"issuer":"https://login.microsoftonline.com/{tenantid}/v2.0"},
    {"kty":"RSA","use":"sig","kid":"C2dE3fH4iJ5kL6mN7oP8qR9sT0uV1w","x5t":"C2dE3fH4iJ5kL6mN7oP8qR9sT0uV1w","n":"wEM...","e":"AQAB","x5c":["MIID..."],"issuer":"https://login.microsoftonline.com/{tenantid}/v2.0"},
    {"kty":"RSA","use":"sig","kid":"E3fH4iJ5kL6mN7oP8qR9sT0uV1wX2y","x5t":"E3fH4iJ5kL6mN7oP8qR9sT0uV1wX2y","n":"rv0...","e":"AQAB","x5c":["MIID..."],"issuer":"https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0"}
  ]
}

署名キー発行者の検証

アプリケーションでは、キーのスコープを制限するために、トークンの署名に使用されるキーに関連付けられているキー ドキュメントの issuer プロパティを使用する必要があります。

  • https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0 のような GUID を含む発行者の値を持つキーは、トークン内の iss クレームと値が完全一致する場合にのみ使用する必要があります。
  • https://login.microsoftonline.com/{tenantid}/v2.0 のようなテンプレート化された発行者値を持つキーは、{tenantid} プレースホルダーのトークン内の tid クレームを置き換えた後、トークン内の iss クレームがこの値と一致する場合にのみ使用してください。

多くのテナントからトークンを受け入れるアプリケーションの場合、テナントに依存しないメタデータを使用する方がより効率的です。

Note

Microsoft Entra のテナントに依存しないメタデータでは、標準の OpenID Connect の場合と同様に、クレームはテナント内で解釈される必要があります。クレームは発行者内で解釈されます。 つまり、{"sub":"ABC123","iss":"https://login.microsoftonline.com/{example-tenant-id}/v2.0","tid":"{example-tenant-id}"}{"sub":"ABC123","iss":"https://login.microsoftonline.com/{another-tenand-id}/v2.0","tid":"{another-tenant-id}"} は、sub は同じですが、sub のようなクレームは発行者/テナントのコンテキスト内で解釈されるため、異なるユーザーを記述しています。

要点

発行者と署名キー発行者の検証方法を要約した擬似コードを次に示します。

  1. 構成されたメタデータ URL からキーを取り込みます
  2. 公開されたキーのいずれかで署名されている場合はトークンをチェックし、そうでない場合は処理を失敗させます
  3. キー ID ヘッダーに基づいて、メタデータ内のキーを識別します。 メタデータ ドキュメントのキーにアタッチされている "issuer" プロパティをチェックします。
    var issuer = metadata["kid"].issuer;
    if (issuer.contains("{tenantId}", CaseInvariant)) issuer = issuer.Replace("{tenantid}", token["tid"], CaseInvariant);
    if (issuer != token["iss"]) throw validationException;
    if (configuration.allowedIssuer != "*" && configuration.allowedIssuer != issuer) throw validationException;
    var issUri = new Uri(token["iss"]);
    if (issUri.Segments.Count < 1) throw validationException;
    if (issUri.Segments[1] != token["tid"]) throw validationException;