早々に結論
Cognitive Services への接続には TLS 1.2 を使いましょう!
ハマったところ
下記ドキュメントの通りで、東日本リージョンの Cognitive Services のエンドポイントなど、比較的新しく展開されたリージョンでは、TLS 1.0 / TLS 1.1 が無効化されています。
Cognitive Services への接続には TLS 1.2 をご利用ください
かたや、.NET Framework 4.5 あたりの HttpClient ではデフォルトで TLS 1.2 は使わないようになってるっぽい感じで、それに気づかずハマり…。
Default SecurityProtocol in .NET 4.5
どんな感じでハマったか
var client = new HttpClient();
//中略
var response = await client.PostAsync(<URL>, <Content>);
みたいな感じで .NET Framework の HttpClient クラスを使って接続しに行ってみたわけですよ。
※なんで SDK 使わないのかというツッコミはあるかもしれませんがw
そしたら例外が…。
System.Net.WebException: 接続が切断されました: 送信時に、予期しないエラーが発生しました。
Fiddler でトレース取ってみたら、どうも TLS のハンドシェイクで失敗しているっぽかったので、調べたら出てまいりました…。
どうやらこれで TLS 1.2 を使うように設定しないといけないらしい。
ServicePointManager.SecurityProtocol Property
というわけでコードをこんな感じに変更。
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
var client = new HttpClient();
//中略
var response = await client.PostAsync(<URL>, <Content>);
これでうまくつながるようになりました!
改めて教訓
- Cognitive Services への接続には TLS 1.2 を使いましょう!
- というか、そもそも SDK が用意されているなら、回り道せずできるだけそっち使いましょうw
- HttpClient クラスの挙動には要注意!
- 上手くいかなかったら Fiddler でデバッグ!
それではまた!
参考ドキュメント
.NET Framework で TLS1.1 および 1.2 を有効化する方法 -まとめ-
Cognitive Services への接続には TLS 1.2 をご利用ください
.NET Framework でのトランスポート層セキュリティ (TLS) のベスト プラクティス
ServicePointManager.SecurityProtocol Property