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 では、Azure Active Directory (Azure AD) v2 アカウント ログイン サービスを使用して、ボットがメッセージを送信するために使用できるセキュリティ トークンを生成します。 このトークンはサービス間トークンであり、ユーザー ログインは不要です。 |
| 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:Azure AD v2 アカウント ログイン サービスにアクセス トークンを要求する
重要
Bot Framework にご利用のボットを登録して、その AppID とパスワードを取得する必要があります (この操作をまだ行っていない場合)。 アクセス トークンを要求するには、ボットの App ID とパスワードが必要です。
ログイン サービスにアクセス トークンを要求するには、次の要求を発行します。MICROSOFT-APP-ID および MICROSOFT-APP-PASSWORD は、ご利用のボットを Bot Framework に登録したときに取得したボットの 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: Azure AD v2 アカウント ログイン サービス応答から JWT トークンを取得する
お使いのアプリケーションがログイン サービスによって認証されると、JSON 応答の本文によってアクセス トークン、その種類、トークンの有効期限 (秒単位) が指定されます。
要求のヘッダーにトークンを Authorization 追加するときは、この応答で指定されている正確な値を使用する必要があります。トークン値をエスケープまたはエンコードしないでください。 アクセス トークンは、有効期限が切れるまで有効です。 トークンの有効期限が切れてもご利用のボットの実行に影響が及ばないように、トークンをキャッシュし、事前に最新の情報に更新しておくこともできます。
この例では、Azure AD v2 アカウント ログイン サービスからの応答を示します。
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 ヘッダーにアクセス トークンを含める必要があります。
トークンの形式が正しく、期限切れではなく、Azure AD v2 アカウント ログイン サービスによって生成された場合、Bot Connector サービスは要求を承認します。 トークンが要求の送信元ボットのものであることを確認するために、追加のチェックが実行されます。
次の例で、要求の Authorization ヘッダーでアクセス トークンを指定する方法を示します。
POST https://smba.trafficmanager.net/apis/v3/conversations/12345/activities
Authorization: Bearer eyJhbGciOiJIUzI1Ni...
(JSON-serialized Activity message goes here)
重要
JWT トークンは、Bot Connector サービスに送信する要求の Authorization ヘッダーにのみ指定します。
セキュリティ保護されていないチャネルでトークンを送信しないでください。また、他のサービスに送信する HTTP 要求に含めないでください。
Azure AD v2 アカウント ログイン サービスから取得する 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
}
注意
実際の場面では、フィールドは異なる可能性があります。 すべての JWT トークンを上記で指定されているように作成し、検証します。
Bot Connector サービスからご利用のボットへの要求を認証する
Bot Connector サービスからご利用のボットに要求が送信されるときは、署名付きの JWT トークンが要求の Authorization ヘッダーで指定されます。 署名付き JWT トークンの認証を検証することにより、Bot Connector サービスからの呼び出しをご利用のボットで認証できます。
Bot Connector サービスからの呼び出しを認証するには:
- ボットは、Bot Connector サービスから送信された要求の承認ヘッダーから 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 時間ごとにドキュメントのローカル キャッシュを更新する必要があります。
各キー内のendorsementsプロパティには、受信要求の Activity オブジェクト内のプロパティでchannelId指定されたチャネル ID が本物であることを確認するために使用できる 1 つ以上の保証文字列が含まれています。 保証が必要なチャネル 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
}
注意
実際の場面では、フィールドは異なる可能性があります。 すべての 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 メタデータ ドキュメントでは、有効な署名キーの一覧を含むもう 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 つを含む "発行者" 要求が含まれています。 両方の発行者の値を確認すると、セキュリティ プロトコル v3.1 と v3.2 の両方の発行者の値が確実にチェックされます。
- トークンに "audience" 要求が含まれ、その値がボットの Microsoft AppID と同じである。
- エミュレーターは、バージョンに応じて、appid 要求 (バージョン 1) または承認されたパーティ要求 (バージョン 2) を介して AppId を送信します。
- トークンの有効期限が切れていない。 業界標準の clock-skew は 5 分です。
- トークンに有効な暗号化署名があり、そのキーが、手順 3 で取得した OpenID キー ドキュメント内の一覧に含まれている。
注意
要件 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
}
注意
実際の場面では、フィールドは異なる可能性があります。 すべての 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/d6d49420-f39b-4df7-a1dc-d59a935871db/ |
| v3.1 2.0 | https://login.microsoftonline.com/d6d49420-f39b-4df7-a1dc-d59a935871db/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 |