VB.NETでWebRequestを使ってSSL通信する



アプリケーションからHTTP通信を行いたい場合はHTTPClientクラスがとても便利ですが、.NETFramework4.5以上でなければ使えないという制限があります。

しかしシステムの制限などにより.NETFramework4以前のバージョンで開発を行わなければならない場合もたまにありますよね。(ないかな?汗)

.NETFramework4で使用できるHttpWebRequestクラスを使ってHTTP通信を行うクライアントプログラムを作成してみたので、メモしておこうと思います。


POSTで送受信するクライアントプログラム

通信先のURLと送信データを引数として受け取るメソッドのサンプルです。
Public Sub httpTest(ByVal sURL As String, ByVal sData As String)

    ''HttpWebRequestインスタンス初期化
    Dim req As HttpWebRequest = WebRequest.Create(sURL)
    ''エンコーディング
    Dim enc As System.Text.Encoding = System.Text.Encoding.GetEncoding("utf-8")
    ''POST送信
    req.Method = "POST"
    ''Content-Length HTTPヘッダー
    req.ContentLength = enc.GetByteCount(sData)
    ''認証情報
    req.Credentials = CredentialCache.DefaultCredentials
    ''Accept HTTPヘッダー
    req.Accept = "application/json"
    ''ContentType HTTPヘッダー
    req.ContentType = "application/json"

    ''要求データ書き込み
    Using reqStream As System.IO.Stream = req.GetRequestStream
        reqStream.Write(enc.GetBytes(sData), 0, enc.GetByteCount(sData))
    End Using

    ''リソースからの応答取得
    Dim resp As HttpWebResponse = req.GetResponse
    ''応答本文格納用変数
    Dim body As String = ""
    ''応答本文読み取り
    Using respStream As System.IO.Stream = resp.GetResponseStream
        Using reader As New System.IO.StreamReader(respStream)
            body = reader.ReadToEnd
        End Using
    End Using

    Console.Writeline(body)
End Sub

SSL通信を行う場合はひと手間必要

上記プログラムには問題があります。

接続先のURLがHTTPSで始まる場合、GetResponseで以下のような例外が発生してしまいます。
System.Net.WebException
接続が切断されました: SSL/TLS のセキュリティで保護されているチャネルに対する信頼関係を確立できませんでした。
検証プロシージャによると、リモート証明書は無効です。

SSL通信に対応する場合は、信頼されない証明書を回避する処理が必要になります。

SSL通信(HTTPS)に対応する

自己証明書などの場合、そのままでは証明書エラーで接続できないので、信頼されない証明書を回避する必要があります。

その1.サーバーの証明書ポリシーを設定する(非推奨)

独自のポリシークラスを作成して、System.Net.ServicePointManager.CertificatePolicyに作成したクラスのインスタンスを設定する方法があります。

※しかしこの方法は非推奨となっており、コンパイルで警告が発生します。(実行は可能)
''サーバー証明書ポリシークラス
Public Class MyPolicy
    Implements System.Net.ICertificatePolicy

    ''証明書チェック(常にTrue)
    Public Function CheckValidationResult(
                        svPoint As ServicePoint _
                        , certificate As X509Certificate _
                        , req As WebRequest _
                        , problem As Integer
                        ) As Boolean _
    Implements ICertificatePolicy.CheckValidationResult
        Return True
    End Function
End Class

作成したクラスは以下のように設定します。
''サーバーの証明書ポリシー設定(非推奨)
    System.Net.ServicePointManager.CertificatePolicy = New MyPolicy
    ''※「警告 BC40000 Public Shared Overloads Property CertificatePolicy As ICertificatePolicy は廃止されています」が発生

その2.SSL証明書の独自検証のコールバックメソッドを設定する

SSL証明書の検証で呼び出されるコールバックメソッドに、信頼されないSSL証明書をOKにするメソッドを設定します。
''信頼されていないSSL証明書を無視するメソッド(何でもTrueで返す)
Private Function MyRemoteCertificateValidationCallback(
                    ByVal sender As Object _
                    , ByVal certificate As X509Certificate _
                    , ByVal chain As X509Chain _
                    , ByVal sslPolicyErrors As Net.Security.SslPolicyErrors
                    ) As Boolean
    Return True
End Function

ServicePointManager.ServerCertificateValidationCallbackプロパティにデリゲートメソッドを設定します。
''SSL証明書検証のコールバックメソッドにデリゲート型メソッド設定
    ServicePointManager.ServerCertificateValidationCallback =
        New Security.RemoteCertificateValidationCallback(AddressOf MyRemoteCertificateValidationCallback)

まとめ

上記1、2、どちらでもSSL通信は可能になりますが、1はビルドで警告が発生するので2が良いでしょう。

以上

<スポンサーリンク>


0 件のコメント :

コメントを投稿