SSL証明書の無いWebサイトに HttpWebRequestでアクセスすると、 AuthenticationException が発生する - C#

SSL証明書の無いWebサイトに HttpWebRequestでアクセスすると、 AuthenticationException例外が発生する現象と、対策について紹介します。

現象の確認

現象を確認するため、下記のプログラムを作成します。

UI

Windows Formアプリケーションを作成し、下図のUIを作成します。ButtonとTextBoxを配置します。

コード

下記のコードを記述します。(ButtonのOnClickイベントを実装します。)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.IO;

namespace HttpsConnectionDemo
{
  public partial class FormNonSSLCertification : Form
  {
    public FormNonSSLCertification()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      HttpWebRequest req = (HttpWebRequest)WebRequest.Create("(SSL証明書の無いhttpsサイトのURL)");
      req.Method = "GET";

      HttpWebResponse res = (HttpWebResponse)req.GetResponse();

      Stream s = res.GetResponseStream();
      StreamReader sr = new StreamReader(s);
      string content = sr.ReadToEnd();

      textBox1.Text = content;
    }
  }
}

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。[button1]をクリックします。


プログラムの実行が停止し、AuthenticationException例外が発生します。


対策

ServicePointManager クラスの ServerCertificateValidationCallback コールバックメソッドを置き換え、常にServerCertificateValidationCallback コールバックがtrueを返すように設定します。

プログラム例

下記のプログラムを作成します。

UI

Windows Formアプリケーションを作成し、下図のUIを作成します。ButtonとTextBoxを配置します。

コード

下記のコードを記述します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

namespace HttpsConnectionDemo
{
  public partial class FormNonSSLCertification : Form
  {
    public FormNonSSLCertification()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(OnRemoteCertificateValidationCallback);

      HttpWebRequest req = (HttpWebRequest)WebRequest.Create("https://192.168.64.80/doc");
      req.Method = "GET";

      HttpWebResponse res = (HttpWebResponse)req.GetResponse();

      Stream s = res.GetResponseStream();
      StreamReader sr = new StreamReader(s);
      string content = sr.ReadToEnd();

      textBox1.Text = content;
    }

    private bool OnRemoteCertificateValidationCallback(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
      return true; 
    }

  }
}

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。[button1]をクリックします。


URLにアクセスでき、ページのコンテンツの取得に成功し、テキストボックスにHTMLの内容が表示されます。


著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2017-09-13
作成日: 2017-02-15
iPentec all rights reserverd.