アプリ開発ときどきアウトドア

主にJavaを使ったアプリ開発やトラブルシューティング等のノウハウ、キャンプや登山の紹介や体験談など。

1. システムエンジニアリング ASP.NET Core 実装技術

ASP.NET Core: IHttpClientFactoryの検証用サンプル

投稿日:2020年4月19日 更新日:

本番環境ではあまり使うことはない、検証環境を想定したサンプルを紹介します。
本来のIHttpClientFactoryの使い方や基本的なサンプルは下記を参考にしていただければと思います。

前提

  • マイクロソフトが推奨するIHttpClientFactoryを使用して、HttpClientクライアントを取得する前提です。
  • サンプルはWindows10 + Visual Studio 2019(ASP.NET Core 3.1)環境で確認しています。

サンプル

既定のクライアントのオプション指定

既定のHttpClientにオプションを指定するインターフェイスは用意されていません。
名前付きクライアントにオプションを指定するインターフェイスはあるので、既定のクライアントを意味するOptions.DefaultName(“”)を指定して、オプションを指定できます。
業務では名前付きクライアントか型付きクライアントを使用すると思うので、これは検証用のTIPSになると思います。

public void ConfigureServices(IServiceCollection services)
{
...
    services.AddHttpClient(Options.DefaultName, options =>
    {
        options.BaseAddress = new Uri("https://localhost:44399");
        options.DefaultRequestHeaders.Add("X-ACCESS-KEY", "secret");
        options.DefaultRequestHeaders.Accept.Clear();
        options.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));
    });
...

サーバ証明書(SSL/TLS)のエラーを無視する

通常、サーバ証明書の有効期限やホスト名の検証に失敗すると、次のようにSSLエラーの例外が発生します。

...
System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
 ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
   at System.Net.Security.SslStream.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception)
...
--- End of stack trace from previous location where exception was thrown ---
   at System.Net.Security.SslStream.ThrowIfExceptional()
...

このようなSSLのエラーを無視して通信を行いたい場合、次のようにサーバ証明書の検証ロジックを変更することで実現できます。(この例では、「常に成功」を返す検証ロジックを追加しています。)

public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpClient("bypass-ssl-validation")
        .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler{ 
            ServerCertificateCustomValidationCallback = (
                httpRequestMessage, cert, certChain, policyErrors) => {
               return true;
            }
        });

この変更を行うと全てのサーバ証明書の検証が無効になってしまいセキュリティが低下するので、検証や開発環境に限定した使用を推奨します。もし本番環境でSSLエラーの問題を解決したい場合、サーバ証明書を正しいものに更新する、信頼するサーバ証明書として登録する等、別の方法を推奨します。

HTTP通信内容のロギング

名前付きクライアントの場合ですが、次のようにSystem.Net.Http.HttpClient.{名前}.ClientHandlerのログレベルをTraceに変更することでHTTP要求/応答のHTTPヘッダをログ出力できます。
HTTPボディをログ出力する場合、HttpClientHandlerの実装が必要になります。

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information",

      // HTTP要求/応答のロギング
      "System.Net.Http.HttpClient.Default.ClientHandler": "Trace",
      "System.Net.Http.HttpClient.basic.ClientHandler": "Trace",
      "System.Net.Http.HttpClient.bypass-ssl-validation.ClientHandler": "Trace"
    }
  }
}

ログ出力の例は次の通りです。

System.Net.Http.HttpClient.basic.LogicalHandler: Information: Start processing HTTP request GET https://localhost:44399/api/SampleApi?arg1=abcxyz!%23$%25%26_%3D-003&arg2=あいうえお
System.Net.Http.HttpClient.basic.ClientHandler: Information: Sending HTTP request GET https://localhost:44399/api/SampleApi?arg1=abcxyz!%23$%25%26_%3D-003&arg2=あいうえお
System.Net.Http.HttpClient.basic.ClientHandler: Trace: Request Headers:
X-ACCESS-KEY: secret
Accept: application/json

System.Net.Http.HttpClient.basic.ClientHandler: Information: Received HTTP response after 147.3151ms - OK
System.Net.Http.HttpClient.basic.ClientHandler: Trace: Response Headers:
Transfer-Encoding: chunked
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET
Date: Sun, 19 Apr 2020 09:59:43 GMT
Content-Type: application/json; charset=utf-8

System.Net.Http.HttpClient.basic.LogicalHandler: Information: End processing HTTP request after 165.0041ms - OK

実際の通信は次のようになっています。
上記ではクエリ文字列の日本語がそのまま出力されていますが、実際には次のようにURLエンコードされています。
また、出力されないヘッダがあることも注意してください。

GET /api/SampleApi?arg1=abcxyz!%23$%25%26_%3D-003&arg2=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A HTTP/1.1
Host: localhost:8080
X-ACCESS-KEY: secret
Accept: application/json
Request-Id: |623d2d43-44...

正確な通信内容を確認したい場合はwiresharkやtcpdump等のパケットキャプチャツールの使用をお薦めします。
HTTP要求/応答をログ出力するDelegatingHandlerを実装することもできますが、上記と同様に取得できないヘッダ情報があったり、勝手にデコードされてたりするので正確ではありません。



(adsbygoogle = window.adsbygoogle || []).push({});


(adsbygoogle = window.adsbygoogle || []).push({});

-1. システムエンジニアリング, ASP.NET Core, 実装技術

執筆者:

関連記事

jQueryによるデフォルトボタンの実装

デフォルトボタンについて Webページ上でエンターキーを押した場合、そのページ上であらかじめ決められたボタンをクリックしたかのように処理を実行する仕組みがある。何らかのデータの検索を行うようなページは …

開発環境のJBoss EAP7にリモートアクセス

開発中のものを他者に見せたり、問題が発生している開発者の開発物を参照するために、eclipse上で起動しているEAP7のWebアプリに別のPCからアクセスしたい場合があります。 このための手順を記載し …

ASP.NET Core: ファイルアップロードの考察

ASP.Net Core(3.1)を使ったファイルアップロードに関する考察です。 元ネタはマイクロソフトのサイトですが、記載内容が私には難しかったり、業務で使用するために悩む部分があったので独自に纏め …

DB操作フレームワーク はJPA or mybatis?

開発に向けた準備で、開発標準を準備するフレームワーク(FW)チーム、それらを使って実装を行う業務チームが集まって、「DB操作を行うためのFWは何を使うか?」という協議になった。 FWチームは、FW・J …

OfficeアプリのコントロールはPowerShellかVBAか?

Windowsサーバの監視のお仕事での話です。 月次で各サーバのパフォーマンスモニタのログファイル(.blg)が送られてきます。このデータ群から、各種のグラフや表を作成して、PowerPointでそれ …

プロフィール ゆっきーです。
都内でシステムエンジニアをやっています。
もっと詳細を見る