zoukankan      html  css  js  c++  java
  • IIS6与IIS7在编程实现HTTPS绑定时的细微差别

    本文章其实最主要信息是:

    问题出在那个小小的*号上——IIS6中不支持通配符,第一部分为空时表示(All Unsigned),而IIS7中同时支持空或通配符的写法,如果为空则自动转为*:443:,我们将调用行改为:
    AddHttpsBinding(":443:", "MY", hash);
    后,问题解决。

    文章转自:http://linwx1978.blog.163.com/blog/static/1504106920111281434624/

    最近刚刚解决了一个困扰了很久的问题,发出来大家共享一下。
    问题很简单,就是我们在做一个自动部署网站的程序,需要同时支持在IIS6与IIS7实现HTTPS,也就是要编程实现增加HTTPS绑定,开始的时候我的代码是这样的:

             private void WriteBinaryArrayToDirectoryEntry(PropertyValueCollection entry, byte[] data)
            {
                string[] arrStr = new string[data.Length];
                for (int i = 0; i < data.Length; i++)
                {
                    arrStr[i] = String.Format("{0:x2}", data[i]);
                }
                object[] arrObj = new object[arrStr.Length];
                arrStr.CopyTo(arrObj, 0);

                entry.Clear();
                entry.Add(arrObj);
            }

           public void AddHttpsBinding(string binding, string nameStore, byte[] hash)
            {
                DirectoryEntry entry = new DirectoryEntry("IIS://localhost/W3SVC/1");//指向Default Web Site
     
               entry.Properties[”SecureBindings"].Clear();
                entry.Properties["SecureBindings"].Add(binding);
                WriteBinaryArrayToDirectoryEntry(entry.Properties["SSLCertHash"], hash);

                entry.CommitChanges();
            }
    其中标出来的那一行需要注意,如果需要指向非缺省的网站就可能需要修改,当然,这是题外话。
    调用如下:
    AddHttpsBinding("*:443:", "MY", hash);
    *:443:的意思是指定443端口,任意IP(All Unassigned IP)。

    结果,在IIS7上运行良好,在IIS6及IIS5上就遇到了很多问题,HTTPS无法访问。

    首先我们检查了HTTPS绑定,结果发现证书绑定失败。用Metabase Explorer检查/LM/W3SVC/1下应该有三项与HTTPS绑定有关的条目,分别是:
    SecureBindings,指定端口、IP及HEADER信息。
    SSLCertHash,指定目标证书的哈希值。
    SSLStoreName,指定目标证书所在的目录。
    绑定成功的情况下,这三个条目都应该出现,并且填入我们指定的值,但上述程序在IIS6上运行之后,只有前两个条目而没有SSLStoreName,导致HTTPS服务无法找到目标证书。
    原因是,在IIS6中,必需设定SSLStoreName,而且还必需在设定SSLCertHash之前。但在IIS7中,SSLStoreName由系统自动设定,如果程序试图自行设定,系统会抛出异常:“A specified logon session does not exist. It may already have been terminated. (Exception from HRESULT: 0x80070520)”。

    结果,我们只好把程序改成这样:
            public void AddHttpsBinding(string binding, string nameStore, byte[] hash)
            {
                DirectoryEntry entry = new DirectoryEntry("IIS://localhost/W3SVC/1");
                entry.Properties[”SecureBindings"].Clear();
                entry.Properties[”SecureBindings"]Add(binding);
                WriteBinaryArrayToDirectoryEntry(entry.Properties["SSLCertHash"], hash);

                entry.CommitChanges();

                if (TryGetValue("IIS://localhost/W3SVC/1""SSLStoreName") == "")
                {
                    entry.Properties[
    "SSLStoreName"].Clear();
                    entry.Properties["SSLStoreName"].Add(nameStore);
                    WriteBinaryArrayToDirectoryEntry(entry.Properties["SSLCertHash"
    ], hash);
                    entry.CommitChanges();
                }
            }
    加上了蓝色的部分,在前面的设定结束之后,测试SSLStoreName是否为空,如果为空,则依次设定SSLStoreName和SSLCertHash。在IIS6和IIS7上测试均成功。

    然后我们就遇到了第二个问题:现在IIS6上绑定是成功的,从IIS管理器上也可以看到绑定的证书信息了,但仍然无法用HTTPS访问,下载了一个微软的SSL工具SSL Diagnostics测试了一下,说绑定的IP与SSL的IP不符,可能有问题。于是我们打开IIS管理器,在网站上点击右键,到属性->Web Site页,点击Advanced,在Multiple SSL identities for this Web Site一栏中,发现IP Address一栏写的居然是255.255.255.255,果然有问题!手动将其改为(All Unsigned)之后,问题解决。

    使用Metabase Explorer检查,发现SecureBindings中写的是:443:,也就是说,问题出在那个小小的*号上——IIS6中不支持通配符,第一部分为空时表示(All Unsigned),而IIS7中同时支持空或通配符的写法,如果为空则自动转为*:443:,我们将调用行改为:
    AddHttpsBinding(":443:", "MY", hash);
    后,问题解决。

  • 相关阅读:
    Hash表的查找-C语言
    二叉排序树-C语言
    线性表的查找算法-C语言
    拓扑排序和关键路径
    图结构的创建与遍历-C语言
    MySQL数据库基本脚本命令
    哈夫曼树编码-C语言
    协程简述
    Python多线程编程-Threading库
    Python多进程编程-multiprocessing库
  • 原文地址:https://www.cnblogs.com/duanweishi/p/4273435.html
Copyright © 2011-2022 走看看