Bot Connector API を使用した認証
ご利用のボットと Bot Connector サービスとの通信は、セキュリティ保護されたチャネル (SSL/TLS) で HTTP を使用して行われます。 ご利用のボットから Connector サービスに要求を送信するときは、Connector サービスでボットの ID を検証するために使用できる情報を含める必要があります。 同様に、Connector サービスからご利用のボットに送信される要求には、ボットでサービスの ID を検証するために使用できる情報が含まれている必要があります。 この記事では、ボットと Bot Connector サービスの間で行われるサービス レベルの認証について、そのテクノロジと要件を説明します。 利用する認証コードを独自に記述する場合、ボットと Bot Connector サービスの間でメッセージを交換できるようにするには、この記事で説明するセキュリティ プロシージャを実装する必要があります。
重要
独自の認証コードを記述する場合は、すべてのセキュリティ プロシージャを正しく実装することが不可欠です。 この記事のすべての手順を実装すれば、攻撃者が、ご利用のボットに送信されたメッセージを読み取ったり、ボットになりすましてメッセージを送信したり、秘密鍵を盗んだりする危険性を軽減できます。
Bot Framework SDK をお使いの場合、この記事で説明するセキュリティ プロシージャは SDK によって自動的に実装されるため、お客様が実装する必要はありません。 登録の際にご利用のボットのために取得した AppID とパスワードを使用してプロジェクトを設定するだけで、あとは SDK によって処理されます。
認証テクノロジ
ボットと Bot Connector の間で信頼を確立するために、次の 4 つの認証テクノロジが使用されます。
テクノロジ | 説明 |
---|---|
SSL/TLS | SSL/TLS は、すべてのサービス間接続に対して使用されます。 X.509v3 証明書が、すべての HTTPS サービスの ID を確立するために使用されます。 クライアントでは、サービスが信頼でき、有効であることを確認するために、必ずサービス証明書を調べる必要があります (この手法では、クライアント証明書は使用されません)。 |
OAuth 2.0 | OAuth 2.0 は Microsoft Entra ID アカウント ログイン サービスを使用して、ボットからメッセージを送信する際に使用できるセキュリティ トークンを生成します。 このトークンはサービス間トークンであり、ユーザー ログインは不要です。 |
JSON Web トークン (JWT) | JSON Web トークンは、ボットとの間で送受信されるトークンをエンコードするために使用されます。 クライアントでは、受信したすべての JWT トークンを検証する必要があります。この記事で説明している要件に従ってください。 |
OpenID メタデータ | Bot Connector サービスからは有効なトークンの一覧が公開されます。これは、既知の静的なエンドポイントにある OpenID メタデータに対して独自の JWT トークンに署名を行うために、このサービスによって使用されます。 |
この記事では、標準的な HTTPS と JSON を通してこれらのテクノロジを使用する方法を説明します。 特殊な SDK は不要ですが、OpenID 用のヘルパーなどは役立つことがあります。
使用しているボットから Bot Connector サービスへの認証要求
Bot Connector サービスと通信するには、次の形式を使用して、各 API 要求の Authorization
ヘッダーでアクセス トークンを指定する必要があります。
Authorization: Bearer ACCESS_TOKEN
ボットの JWT トークンを取得して使用するには:
- ボットが MSA ログイン サービスに GET HTTP 要求を送信します。
- サービスからの応答には、使用する JWT トークンが含まれています。
- ボットは、Bot Connector サービスへの要求の Authorization ヘッダーにこの JWT トークンを含めます。
手順 1: Microsoft Entra ID アカウント ログイン サービスにアクセス トークンを要求する
重要
Bot Framework にご利用のボットを登録して、その AppID とパスワードを取得する必要があります (この操作をまだ行っていない場合)。 アクセス トークンを要求するには、ボットの App ID とパスワードが必要です。
ボット ID は、いくつかの方法で Azure で管理できます。
- ボットの認証情報を自分で管理する必要がないように、ユーザー割り当てマネージド ID として管理する。
- シングルテナント アプリとして管理する。
- マルチテナント アプリとして管理する。
ボットのアプリケーションの種類に基づいてアクセス トークンを要求します。
ログイン サービスにアクセス トークンを要求するには、次の要求を発行します。MICROSOFT-APP-ID および MICROSOFT-APP-PASSWORD は、ご利用のボットをボット サービスに登録したときに取得したボットの AppID とパスワードに置き換えてください。
POST https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=MICROSOFT-APP-ID&client_secret=MICROSOFT-APP-PASSWORD&scope=https%3A%2F%2Fapi.botframework.com%2F.default
手順 2: Microsoft Entra ID アカウントのログイン サービス応答から JWT トークンを取得する
お使いのアプリケーションがログイン サービスによって認証されると、JSON 応答の本文によってアクセス トークン、その種類、トークンの有効期限 (秒単位) が指定されます。
トークンを要求の Authorization
ヘッダーに追加するときは、この応答で指定されている値のとおりに使用する必要があります (トークンの値をエスケープしたりエンコードしたりしないでください)。 アクセス トークンは、有効期限が切れるまで有効です。 トークンの有効期限が切れてもご利用のボットの実行に影響が及ばないように、トークンをキャッシュし、事前に最新の情報に更新しておくこともできます。
この例では、Microsoft Entra ID アカウント ログイン サービスからの応答を示しています。
HTTP/1.1 200 OK
... (other headers)
{
"token_type":"Bearer",
"expires_in":3600,
"ext_expires_in":3600,
"access_token":"eyJhbGciOiJIUzI1Ni..."
}
手順 3: 要求の Authorization ヘッダーで JWT トークンを指定する
Bot Connector サービスに API 要求を送信するときは、次の形式を使用して要求の Authorization
ヘッダーでアクセス トークンを指定する必要があります。
Authorization: Bearer ACCESS_TOKEN
Bot Connector サービスに送信するすべての要求で、Authorization
ヘッダーにアクセス トークンを含める必要があります。
トークンが正しい形式であり、有効期限が切れておらず、Microsoft Entra ID アカウント ログイン サービスによって生成されたものである場合、要求は Bot Connector サービスによって認証されます。 トークンが要求の送信元ボットのものであることを確認するために、追加のチェックが実行されます。
次の例で、要求の Authorization
ヘッダーでアクセス トークンを指定する方法を示します。
POST https://smba.trafficmanager.net/teams/v3/conversations/12345/activities
Authorization: Bearer eyJhbGciOiJIUzI1Ni...
(JSON-serialized Activity message goes here)
重要
JWT トークンは、Bot Connector サービスに送信する要求の Authorization
ヘッダーにのみ指定します。
セキュリティ保護されていないチャネルでトークンを送信しないでください。また、他のサービスに送信する HTTP 要求に含めないでください。
Microsoft Entra ID アカウント ログイン サービスから取得する JWT トークンはパスワードと同等のものであるため、細心の注意を払って扱う必要があります。 トークンを所持していれば、誰でもそれを使用して、お使いのボットの代理として操作を実行できてしまいます。
ボットからコネクタ: サンプル JWT コンポーネント
header:
{
typ: "JWT",
alg: "RS256",
x5t: "<SIGNING KEY ID>",
kid: "<SIGNING KEY ID>"
},
payload:
{
aud: "https://api.botframework.com",
iss: "https://sts.windows.net/d6d49420-f39b-4df7-a1dc-d59a935871db/",
nbf: 1481049243,
exp: 1481053143,
appid: "<YOUR MICROSOFT APP ID>",
... other fields follow
}
Note
実際の場面では、フィールドは異なる可能性があります。 すべての JWT トークンを上記で指定されているように作成し、検証します。
Bot Connector サービスからご利用のボットへの要求を認証する
Bot Connector サービスからご利用のボットに要求が送信されるときは、署名付きの JWT トークンが要求の Authorization
ヘッダーで指定されます。 署名付き JWT トークンの認証を検証することにより、Bot Connector サービスからの呼び出しをご利用のボットで認証できます。
Bot Connector からご利用のボットへの呼び出しを認証する:
- ボットが、Bot Connector サービスから送信される要求の Authorization ヘッダーから、この JWT トークンを取得します。
- ボットが、Bot Connector サービスの OpenID メタデータ ドキュメントを取得します。
- ボットが、ドキュメントから有効な署名キーの一覧を取得します。
- ボットが JWT トークンの信頼性を検証します。
手順 2: OpenID メタデータ ドキュメントを取得する
OpenID メタデータ ドキュメントでは、Bot Connector サービスの有効な署名キーの一覧を含むもう 1 つのドキュメントの場所が指定されます。 OpenID メタデータ ドキュメントを取得するには、次の要求を HTTPS 経由で発行します。
GET https://login.botframework.com/v1/.well-known/openidconfiguration
ヒント
これは静的な URL であり、アプリケーションにハードコーディングすることができます。
次の例で、GET
要求に対して返される OpenID メタデータ ドキュメントを示します。 jwks_uri
プロパティでは、Bot Connector サービスの有効な署名キーが含まれるドキュメントの位置が指定されます。
{
"issuer": "https://api.botframework.com",
"authorization_endpoint": "https://invalid.botframework.com",
"jwks_uri": "https://login.botframework.com/v1/.well-known/keys",
"id_token_signing_alg_values_supported": [
"RS256"
],
"token_endpoint_auth_methods_supported": [
"private_key_jwt"
]
}
手順 3: 有効な署名キーの一覧を取得する
有効な署名キーの一覧を取得するには、OpenID メタデータ ドキュメントで jwks_uri
プロパティによって指定されている URL に、HTTPS 経由で GET
要求を発行します。 次に例を示します。
GET https://login.botframework.com/v1/.well-known/keys
応答の本体には、ドキュメントが JWK 形式で指定されますが、各キーに対応する追加のプロパティ endorsements
も含まれています。
ヒント
キーのリストは安定しており、キャッシュすることができますが、新しいキーはいつでも追加できます。 これらのキーが使用される前にボットにドキュメントの最新のコピーがあることを確認するには、すべてのボット インスタンスで少なくとも 24 時間ごとに 1 回、ドキュメントのローカル キャッシュを更新する必要があります。
各キーの endorsements
プロパティには、少なくとも 1 つの承認文字列が含まれており、これを使用することにより、受信した要求のアクティビティオブジェクト内で channelId
プロパティによって指定されているチャンネル ID が正しいことを検証できます。 保証が必要なチャネル ID の一覧は、各ボット内で設定できます。 既定では、これは公開済みのすべてのチャネル ID の一覧になりますが、ボットの開発者は一部のチャネル ID 値を選択し、何らかの方法でオーバーライドすることができます。
手順 4: JWT トークンを検証する
Bot Connector サービスから送信されたトークンの信頼性を検証するには、要求の Authorization
ヘッダーからトークンを抽出し、トークンを解析し、その内容を確認して署名を検証する必要があります。
多くのプラットフォームに JWT 解析ライブラリが用意されており、大部分のユーザーは JWT トークン用の安全で信頼性のある解析を実装しています。それでも、通常はトークンの特定の特性 (発行者、オーディエンスなど) に正しい値が含まれるようにするために、これらのライブラリを設定する必要があります。 トークンの解析では、トークンが確実に以下の要件を満たすように、解析ライブラリを設定するか、独自の検証を作成する必要があります。
- トークンが HTTP
Authorization
ヘッダーに含まれ、"Bearer" スキームで送信された。 - トークンは有効な JSON であり、JWT 標準に準拠している。
- トークンに "issuer" 要求が含まれ、その値が
https://api.botframework.com
である。 - トークンに "audience" 要求が含まれ、その値がボットの Microsoft AppID と同じである。
- トークンの有効期限が切れていない。 業界標準の clock-skew は 5 分です。
- トークンに有効な暗号化署名があり、そのキーが、手順 2 で取得した Open ID メタデータ ドキュメントの
id_token_signing_alg_values_supported
プロパティで指定されている署名アルゴリズムを使用して手順 3 で取得した OpenID キー ドキュメント内の一覧に含まれている。 - トークンに "serviceUrl" 要求が含まれ、その値が、受信した要求の Activity オブジェクトのルートにある
serviceUrl
プロパティと一致する。
チャネル ID に対して保証が必要な場合は、以下が適用されます。
- ご利用のボットにそのチャネル ID で送信されるすべての
Activity
オブジェクトには、そのチャネルに対する保証で署名された JWT トークンが付随していることを要件とする必要があります。 - 承認が存在しない場合、ご利用のボットは、HTTP 403 (アクセス不可) 状態コードを返すして要求を拒否する必要があります。
重要
これらの要件はすべて重要ですが、要件 4 と 6 は特に重要です。 これらの検証要件のすべてを実装しないと、ボットは攻撃に対して無防備になり、ボットから JWT トークンが漏洩するおそれがあります。
実装する際は、ボットに送信される JWT トークンの検証を無効にするようなやり方で公開されないようにする必要があります。
コネクタからボット: サンプル JWT コンポーネント
header:
{
typ: "JWT",
alg: "RS256",
x5t: "<SIGNING KEY ID>",
kid: "<SIGNING KEY ID>"
},
payload:
{
aud: "<YOU MICROSOFT APP ID>",
iss: "https://api.botframework.com",
nbf: 1481049243,
exp: 1481053143,
... other fields follow
}
Note
実際の場面では、フィールドは異なる可能性があります。 すべての JWT トークンを上記で指定されているように作成し、検証します。
Bot Framework Emulator からご利用のボットへの要求を認証する
Bot Framework Emulator は、ご利用のボットの機能をテストするために使用できるデスクトップ ツールです。 Bot Framework Emulator では、上記の説明と同じ認証テクノロジが使用されますが、実際の Bot Connector サービスを偽装することはできません。
代わりに、ボットによって作成されるものと同じトークンを作成するためにエミュレーターをご利用のボットに接続するときには、ご自身が指定する Microsoft AppID と Microsoft AppPassword が使用されます。
エミュレーターからご利用のボットに要求が送信されるときは、要求の Authorization
ヘッダー内に JWT トークンが指定されるため、実質的にボット独自の認証情報を使用して要求が認証されることになります。
認証ライブラリを実装してある場合に Bot Framework Emulator からの要求を受け入れるには、この追加的な検証パスを指定する必要があります。 このパスの構造はコネクタから > ボットへの検証パスと似ていますが、Bot Connector の OpenID ドキュメントではなく MSA の OpenID ドキュメントが使用されます。
Bot Framework Emulator からの呼び出しを認証するには:
- ボットは、Bot Framework Emulator から送信される要求の Authorization ヘッダーから JWT トークンを取得します。
- ボットが、Bot Connector サービスの OpenID メタデータ ドキュメントを取得します。
- ボットが、ドキュメントから有効な署名キーの一覧を取得します。
- ボットが JWT トークンの信頼性を検証します。
手順 2: MSA OpenID メタデータ ドキュメントを取得する
OpenID メタデータ ドキュメントでは、有効な署名キーの一覧を含むもう 1 つのドキュメントの場所が指定されます。 MSA OpenID メタデータ ドキュメントを取得するには、次の要求を HTTPS 経由で発行します。
GET https://login.microsoftonline.com/botframework.com/v2.0/.well-known/openid-configuration
次の例で、GET
要求に対して返される OpenID メタデータ ドキュメントを示します。 jwks_uri
プロパティでは、有効な署名キーが含まれるドキュメントの位置が指定されます。
{
"authorization_endpoint":"https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
"token_endpoint":"https://login.microsoftonline.com/common/oauth2/v2.0/token",
"token_endpoint_auth_methods_supported":["client_secret_post","private_key_jwt"],
"jwks_uri":"https://login.microsoftonline.com/common/discovery/v2.0/keys",
...
}
手順 3: 有効な署名キーの一覧を取得する
有効な署名キーの一覧を取得するには、OpenID メタデータ ドキュメントで jwks_uri
プロパティによって指定されている URL に、HTTPS 経由で GET
要求を発行します。 次に例を示します。
GET https://login.microsoftonline.com/common/discovery/v2.0/keys
Host: login.microsoftonline.com
応答の本体には、ドキュメントが JWK 形式で指定されます。
手順 4: JWT トークンを検証する
エミュレーターから送信されたトークンの信頼性を検証するには、要求の Authorization
ヘッダーからトークンを抽出し、トークンを解析し、その内容を確認して署名を検証する必要があります。
多くのプラットフォームに JWT 解析ライブラリが用意されており、大部分のユーザーは JWT トークン用の安全で信頼性のある解析を実装しています。それでも、通常はトークンの特定の特性 (発行者、オーディエンスなど) に正しい値が含まれるようにするために、これらのライブラリを設定する必要があります。 トークンの解析では、トークンが確実に以下の要件を満たすように、解析ライブラリを設定するか、独自の検証を作成する必要があります。
- トークンが HTTP
Authorization
ヘッダーに含まれ、"Bearer" スキームで送信された。 - トークンは有効な JSON であり、JWT 標準に準拠している。
- トークンに、非政府機関のケースでハイライトされた値の 1 つを含む「issuer」請求が含まれている。 (両方の issuer 値を確認することで、セキュリティ プロトコル v3.1 と v3.2 両方の issuer 値を確実にチェックすることができます。)
- トークンに "audience" 要求が含まれ、その値がボットの Microsoft AppID と同じである。
- エミュレーターは、バージョンに応じて、appid 請求 (バージョン 1) または承認されたパーティ要求 (バージョン 2) を介して AppId を送信します。
- トークンの有効期限が切れていない。 業界標準の clock-skew は 5 分です。
- トークンに有効な暗号化署名があり、そのキーが、手順 3 で取得した OpenID キー ドキュメント内の一覧に含まれている。
Note
要件 5 は、エミュレーター検証パスに固有です。
トークンがこれらの要件のすべてを満たさない場合、ご利用のボットは、HTTP 403 (アクセス不可) 状態コードを返すことによって要求を終了する必要があります。
重要
これらの要件はすべて重要ですが、要件 4 と 7 は特に重要です。 これらの検証要件のすべてを実装しないと、ボットは攻撃に対して無防備になり、ボットから JWT トークンが漏洩するおそれがあります。
エミュレーターからボット: サンプル JWT コンポーネント
header:
{
typ: "JWT",
alg: "RS256",
x5t: "<SIGNING KEY ID>",
kid: "<SIGNING KEY ID>"
},
payload:
{
aud: "<YOUR MICROSOFT APP ID>",
iss: "https://sts.windows.net/d6d49420-f39b-4df7-a1dc-d59a935871db/",
nbf: 1481049243,
exp: 1481053143,
... other fields follow
}
Note
実際の場面では、フィールドは異なる可能性があります。 すべての JWT トークンを上記で指定されているように作成し、検証します。
セキュリティ プロトコルの変更
ボットからコネクタへの認証
OAuth ログイン URL
プロトコルのバージョン | 有効な値 |
---|---|
v3.1 および v3.2 | https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token |
OAuth の範囲
プロトコルのバージョン | 有効な値 |
---|---|
v3.1 および v3.2 | https://api.botframework.com/.default |
コネクタからボットへの認証
OpenID メタデータ ドキュメント
プロトコルのバージョン | 有効な値 |
---|---|
v3.1 および v3.2 | https://login.botframework.com/v1/.well-known/openidconfiguration |
JWT 発行者
プロトコルのバージョン | 有効な値 |
---|---|
v3.1 および v3.2 | https://api.botframework.com |
エミュレーターからボットへの認証
OAuth ログイン URL
プロトコルのバージョン | 有効な値 |
---|---|
v3.1 および v3.2 | https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token |
OAuth の範囲
プロトコルのバージョン | 有効な値 |
---|---|
v3.1 および v3.2 | ご利用のボットの Microsoft アプリ ID + /.default |
JWT のオーディエンス
プロトコルのバージョン | 有効な値 |
---|---|
v3.1 および v3.2 | ご利用のボットの Microsoft アプリ ID |
JWT 発行者
プロトコルのバージョン | 有効な値 |
---|---|
v3.1 1.0 | https://sts.windows.net/aaaabbbb-0000-cccc-1111-dddd2222eeee/ |
v3.1 2.0 | https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0 |
v3.2 1.0 | https://sts.windows.net/f8cdef31-a31e-4b4a-93e4-5f571e91255a/ |
v3.2 2.0 | https://login.microsoftonline.com/f8cdef31-a31e-4b4a-93e4-5f571e91255a/v2.0 |
非政府機関のケースの ハイライトされた値も参照してください。
OpenID メタデータ ドキュメント
プロトコルのバージョン | 有効な値 |
---|---|
v3.1 および v3.2 | https://login.microsoftonline.com/botframework.com/v2.0/.well-known/openid-configuration |