ボットは、セキュリティで保護されたチャネル (SSL/TLS) 経由で HTTP を使用して Bot Connector サービスと通信します。 ボットがコネクタ サービスに要求を送信するときは、コネクタ サービスがその ID を確認するために使用できる情報を含める必要があります。 同様に、コネクタ サービスがボットに要求を送信するときは、ボットがその ID を確認するために使用できる情報を含める必要があります。 この記事では、ボットと Bot Connector サービスの間で行われるサービス レベル認証の認証テクノロジと要件について説明します。 独自の認証コードを記述する場合は、ボットが Bot Connector サービスとメッセージを交換できるように、この記事で説明されているセキュリティ手順を実装する必要があります。
Important
独自の認証コードを記述する場合は、すべてのセキュリティ手順を正しく実装することが重要です。 この記事のすべての手順を実装することで、攻撃者がボットに送信されたメッセージを読み取り、ボットを偽装するメッセージを送信し、秘密鍵を盗むことができるリスクを軽減できます。
Bot Framework SDK を使用している場合は、SDK によって自動的に行われるため、この記事で説明されているセキュリティ手順を実装する必要はありません。 登録時にボット用に取得したアプリ ID とパスワードを使用してプロジェクトを構成するだけで、SDK は残りの部分を処理します。
認証テクノロジ
ボットと Bot Connector の間の信頼を確立するには、次の 4 つの認証テクノロジが使用されます。
| テクノロジ | Description |
|---|---|
| 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 サービスへの要求の承認ヘッダーにこの JWT トークンを含めます。
手順 1: Microsoft Entra ID アカウント ログイン サービスにアクセス トークンを要求する
Important
まだ行っていない場合は、 ボットを Bot Framework に登録して、その AppID とパスワードを取得する必要があります。 アクセス トークンを要求するには、ボットのアプリ ID とパスワードが必要です。
ボット ID は、いくつかの異なる方法でAzureで管理できます。
- ボットの認証情報を自分で管理する必要がないように、ユーザー割り当てマネージド ID として管理する。
- シングルテナント アプリとして動作する。
- マルチテナントアプリとして利用する。
ボットのアプリケーションの種類に基づいてアクセス トークンを要求します。
ログイン サービスからアクセス トークンを要求するには、次の要求を発行します。MICROSOFT-APP-ID と MICROSOFT-APP-PASSWORD は、ボットをBot Serviceに登録したときに取得したボットの 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)
Important
Bot Connector サービスに送信する要求の Authorization ヘッダーにのみ JWT トークンを指定します。
セキュリティで保護されていないチャネル経由でトークンを送信しないでください。また、他のサービスに送信する 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 サービスは、ボットに要求を送信するときに、要求の Authorization ヘッダーに署名済みの JWT トークンを指定します。 ボットは、署名された JWT トークンの信頼性を確認することで、Bot Connector サービスからの呼び出しを認証できます。
Bot Connector サービスからの呼び出しを認証するには:
- ボットは、Bot Connector サービスから送信された要求の承認ヘッダーから JWT トークンを取得します。
- ボットは、Bot Connector サービスの OpenID メタデータ ドキュメントを取得します。
- ボットは、ドキュメントから有効な署名キーの一覧を取得します。
- ボットは JWT トークンの信頼性を検証します。
手順 2: OpenID メタデータ ドキュメントを取得する
OpenID メタデータ ドキュメントは、Bot Connector サービスの有効な署名キーを一覧表示する 2 番目のドキュメントの場所を指定します。 OpenID メタデータ ドキュメントを取得するには、HTTPS 経由で次の要求を発行します。
GET https://login.botframework.com/v1/.well-known/openidconfiguration
Tip
これは、アプリケーションにハードコーディングできる静的 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) も含まれます。
Tip
キーの一覧は安定しており、キャッシュできますが、新しいキーはいつでも追加できます。 これらのキーが使用される前に、ボットにドキュメントの up-to-date コピーがあることを確認するには、すべてのボット インスタンスが少なくとも 24 時間に 1 回、ドキュメントのローカル キャッシュを更新する必要があります。
各キー内の endorsements プロパティには、受信要求の Activity オブジェクト内の channelId プロパティで指定されたチャネル ID が本物であることを確認するために使用できる 1 つ以上の保証文字列が含まれています。 保証を必要とするチャネル ID の一覧は、各ボット内で構成できます。 既定では、公開されているすべてのチャネル ID の一覧になりますが、ボット開発者はどちらの方法でも選択したチャネル ID 値をオーバーライドできます。
手順 4: JWT トークンを確認する
Bot Connector サービスによって送信されたトークンの信頼性を確認するには、要求の Authorization ヘッダーからトークンを抽出し、トークンを解析し、その内容を確認し、その署名を確認する必要があります。
JWT 解析ライブラリは多くのプラットフォームで使用でき、ほとんどの場合、JWT トークンの安全で信頼性の高い解析を実装しますが、通常、トークンの特定の特性 (発行者、対象ユーザーなど) に正しい値が含まれるようにこれらのライブラリを構成する必要があります。 トークンを解析するときは、解析ライブラリを構成するか、トークンが次の要件を満たしていることを確認するために独自の検証を記述する必要があります。
- トークンは、"Bearer" スキームを使用して HTTP
Authorizationヘッダーで送信されました。 - トークンは、 JWT 標準に準拠する有効な JSON です。
- トークンには、値が
https://api.botframework.comの "発行者" 要求が含まれています。 - トークンには、ボットの Microsoft アプリ ID と等しい値を持つ "対象ユーザー" 要求が含まれています。
- トークンは有効期間内です。 業界標準のクロック スキューは 5 分です。
- トークンには有効な暗号化署名があり、手順 3 で取得した OpenID キー ドキュメントにキーが記載されています。このキーは、手順 2 で取得した Open ID メタデータ ドキュメントの
id_token_signing_alg_values_supportedプロパティで指定された署名アルゴリズムを使用します。 - トークンには、受信要求の Activity オブジェクトのルートにある
serviceUrlプロパティと一致する値を持つ "serviceUrl" 要求が含まれています。
チャネル ID の保証が必要な場合:
- そのチャネル ID を使用してボットに送信された
Activityオブジェクトには、そのチャネルの保証で署名された JWT トークンが添付されている必要があります。 - 保証が存在しない場合、ボットは HTTP 403 (禁止) 状態コードを返して要求を拒否する必要があります。
Important
これらの要件はすべて重要であり、特に要件 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アプリ ID とMicrosoftアプリ パスワードを使用して、ボットが作成したものと同じトークンを作成します。
エミュレーターは、ボットに要求を送信するときに、要求の Authorization ヘッダーに JWT トークンを指定します。基本的には、ボット独自の資格情報を使用して要求を認証します。
認証ライブラリを実装していて、Bot Framework Emulator からの要求を受け入れる場合は、この追加の検証パスを追加する必要があります。 このパスは、 コネクタ -> ボット 検証パスと構造的に似ていますが、Bot Connector の OpenID ドキュメントではなく MSA の OpenID ドキュメントを使用します。
Bot Framework Emulator からの呼び出しを認証するには:
- ボットは、Bot Framework Emulator から送信された要求の承認ヘッダーから JWT トークンを取得します。
- ボットは、Bot Connector サービスの OpenID メタデータ ドキュメントを取得します。
- ボットは、ドキュメントから有効な署名キーの一覧を取得します。
- ボットは JWT トークンの信頼性を検証します。
手順 2: MSA OpenID メタデータ ドキュメントを取得する
OpenID メタデータ ドキュメントは、有効な署名キーを一覧表示する 2 番目のドキュメントの場所を指定します。 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 トークンの安全で信頼性の高い解析を実装しますが、通常、トークンの特定の特性 (発行者、対象ユーザーなど) に正しい値が含まれるようにこれらのライブラリを構成する必要があります。 トークンを解析するときは、解析ライブラリを構成するか、トークンが次の要件を満たしていることを確認するために独自の検証を記述する必要があります。
- トークンは、"Bearer" スキームを使用して HTTP
Authorizationヘッダーで送信されました。 - トークンは、 JWT 標準に準拠する有効な JSON です。
- トークンには、該当するセキュリティ プロトコルの発行者要求が含まれています。 現在の実装については、Microsoft.Agents.Connector を参照してください。
- トークンには、ボットの Microsoft アプリ ID と等しい値を持つ "対象ユーザー" 要求が含まれています。
- エミュレーターは、バージョンに応じて、appid 要求 (バージョン 1) または承認されたパーティ要求 (バージョン 2) を介して AppId を送信します。
- トークンは有効期間内です。 業界標準のクロック スキューは 5 分です。
- トークンには、 手順 3 で取得した OpenID キー ドキュメントに記載されているキーを含む有効な暗号化署名があります。
Note
要件 5 は、エミュレーターの検証パスに固有のものです。
トークンがこれらの要件をすべて満たしていない場合、ボットは HTTP 403 (Forbidden) 状態コードを返して要求を終了する必要があります。
Important
これらの要件はすべて重要であり、特に要件 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 |
現在の実装については、Microsoft.Agents.Connector を参照してください。
OpenID メタデータ ドキュメント
| プロトコルのバージョン | 有効な値 |
|---|---|
| v3.1 & v3.2 | https://login.microsoftonline.com/botframework.com/v2.0/.well-known/openid-configuration |