以编程方式删除安全站点会破坏其他绑定

时间:2016-06-13 14:31:08

标签: c# ssl iis https web

我有清除未使用网站的服务。

using (var serverMgr = new ServerManager())
{
    var sitename = $"site-{instanceName}";

    if (IsWebsiteExists(serverMgr, sitename))
    {
        logger.Debug($"Deleting instance '{sitename}' from www server...");
        var site = serverMgr.Sites.SingleOrDefault(x => x.Name == sitename);
        if (site != null)
        {
            serverMgr.Sites.Remove(site);
        }

        var appPool = serverMgr.ApplicationPools.SingleOrDefault(x => x.Name == sitename);
        if (appPool != null)
        {
            serverMgr.ApplicationPools.Remove(appPool);
        }
        serverMgr.CommitChanges();
    }
}

上面的代码按预期工作,但会破坏使用相同证书的其他网站。其他站点意外地在https绑定中具有未选择的证书,并且它们停止工作。这真令人讨厌。

为什么呢?它是我的代码中的错误还是我应该更改它?是IIS的错误吗?

3 个答案:

答案 0 :(得分:1)

Site类表示IIS中Site的所有常用方法和属性。所有配置也由嵌套类型完成。这意味着:我们没有办法创建新的NestedObject,我们必须从工厂(ServerManager)获取它,并且它可能从一些静态垃圾中获得所需的所有东西(在IIS情况下甚至更糟)

我们的目标是删除网站,而不会影响负责证书的嵌套类型。那种类型是绑定。 Site具有readonly Binding Property,它返回BindingCollection,这是嵌套发生的地方。这个集合由需要绑定的每个人共享。每个人都可以搞砸别人。即ServerManager为我们创建Site对象,某种程度上更深层次的东西(IIS c#clone)为我们的特定Site对象创建绑定对象。删除Site对象时,将从IIS中删除,并且此Site Site对象的Bindings对象也将被删除。 IIS通过自己的界面执行此操作,也必须使用c#代码,并且必须阻止我们更改此行为(我认为只有IIS团队可以更改它;))。但我们可以抵制这种不可见的行为;)

尝试这样的代码:

       Site site = _server.Sites[name];
       if (site == null)
         return;

       var bindings = site.Bindings.ToList();

       foreach (Binding binding in bindings)
       {
          site.Bindings.Remove(binding, true);
       }
          _server.Sites.Remove(site);

          _server.CommitChanges();

Remove(binding,true)仅删除配置,而不删除绑定本身。它的新功能,需要实际的Microsoft.Web.Administrative MSDN:https://msdn.microsoft.com/en-us/library/mt668014(v=vs.90).aspx

在此功能之前,这是一个很好的解决方案: "序列化"绑定对象,并将其放回去 - 通常只是保存添加绑定所需的somwhere数据。字典? MemoryStream的?无所谓。大图:

Wana删除包含共享绑定的页面? 查找共享这些绑定的所有页面,记住它们。 "序列化"绑定。 删除页面。 迭代以前查找过的网站的集合,将绑定放回给每个人。即一次迭代可能看起来:_siteFromColletion.Bindings.Add(bindingInfo,certHash,certStorename)

bindingInfo是字符串 certHash字节数组 certStorename是字符串 您需要将与certifcate的绑定添加到Site

HND!

答案 1 :(得分:1)

删除网站前删除所有绑定:

using (var iisManager = new ServerManager)
{
    Site site = iisManager.Sites[siteName];
    site.Bindings.Clear();
    iisManager.CommitChanges();

    site = iisManager.Sites[siteName];
    iisManager.Sites.Remove(site);
    iisManager.CommitChanges();
}

删除绑定后调用CommitChanges很重要。此外,您必须在之后再次查询该网站,否则您将获得InvalidOperationException

另外,使用这种方法,在删除网站后调用NotImplementedException时,在某些系统上不会获得CommitChanges,因此它可以同时解决两个恼人的问题。

如果您的目标是.NET Framework 4.6.1或更高版本,您也可以使用此解决方案:https://stackoverflow.com/a/37802922/2279059

答案 2 :(得分:0)

解决方案是删除绑定配置部分本身。从xml内部删除部分配置部分,但仅限于此网站内部。你的回答卡米尔给了我一个提示。

using (var serverMgr = new ServerManager())
{
    if (IsWebsiteExists(serverMgr, sitename))
    {
        var site = serverMgr.Sites.SingleOrDefault(x => x.Name == sitename);
        if (site != null)
        {
            logger.Trace($"Stopping site '{sitename}'...");
            site.Stop();
            logger.Trace($"Deleting bindings collection for '{sitename}'...");

            site.Bindings.Delete(); // <-- deleting bindings config section itself
        }
        serverMgr.CommitChanges();
    }
}