基于 IIS 绑定将 WCF 端点动态绑定到 HTTPS

Posted

技术标签:

【中文标题】基于 IIS 绑定将 WCF 端点动态绑定到 HTTPS【英文标题】:Dynamically Bind WCF Endpoints To HTTPS Based on IIS Bindings 【发布时间】:2020-06-19 16:09:14 【问题描述】:

我有一个 WCF 服务,我正在将其从 HTTP 转换为 HTTPS。客户端当前具有此服务的硬编码 HTTP URL。服务器使用 Web.config 文件中的一些自定义行为来绑定服务:

  <service behaviorConfiguration="MyServiceBehaviors" name="MyService">
    <endpoint address="" behaviorConfiguration="MyEndpointBehaviors" binding="customBinding" bindingConfiguration="MyHttpCustomBinding" name="MyService" contract="IMyService" />
  </service>

我想将 WCF 服务绑定到 HTTP 和 HTTPS。我可以使用 Web.config 文件中的两个条目来做到这一点:

  <service behaviorConfiguration="MyServiceBehaviors" name="MyService">
    <endpoint address="" behaviorConfiguration="MyEndpointBehaviors" binding="customBinding" bindingConfiguration="MyHttpCustomBinding" name="MyService" contract="IMyService" />
    <endpoint address="" behaviorConfiguration="MyEndpointBehaviors" binding="customBinding" bindingConfiguration="MyHttpsCustomBinding" name="MyService" contract="IMyService" />
  </service>

我还要求服务器一开始可能没有启用 HTTPS。所以在 WCF 服务启动时,IIS 可能没有绑定到 HTTPS 端口 443。

如果 IIS没有绑定到 HTTPS,并且 Web.config 绑定到两个端点,如上例,并且客户端尝试在 HTTP 端点上激活服务,则服务无法启动有以下激活异常:

WebHost 未能处理请求。发件人信息: System.ServiceModel.ServiceHostingEnvironment+HostingManager/45653674 异常:System.ServiceModel.ServiceActivationException:服务 '/MyApp/MyService.svc' 无法激活,因为在执行过程中出现异常 汇编。异常消息是:找不到基地址 与绑定 CustomBinding 的端点的方案 https 匹配。 注册的基地址方案是 [http]。

我认为只有在 IIS 中启用 HTTPS 时,WCF 服务才需要绑定到 HTTPS。我在 Web.config 文件中看不到实现此目的的方法,因此我认为我需要进行一些动态服务器绑定。

如何根据 IIS 配置有选择地绑定 WCF 中的 HTTP 和 HTTPS 端点?

如果 IIS 绑定更改为添加/删除 HTTPS,我也看不到可以通知服务的方式,但我可以要求管理员回收应用程序池/IISRESET/reboot 以使服务使用更新设置。

【问题讨论】:

【参考方案1】:

我能够通过以下步骤使其工作:

在 MyService.svc 文件中添加一个 Factory 属性,以便能够构建服务:

<%@ ServiceHost Language="C#" Debug="true"
    Service="MyService"
    Factory="MyServiceFactory" %>

在 WCF 服务 DLL 中创建工厂类:

public class MyServiceFactory : ServiceHostFactory

    public override ServiceHostBase CreateServiceHost(string service, Uri[] baseAddresses)
    
        return CreateServiceHost(typeof(MyService), baseAddresses);
    

    protected override ServiceHost CreateServiceHost(Type t, Uri[] baseAddresses)
    
        var serviceHost = new ServiceHost(t, baseAddresses);
        foreach (Uri address in baseAddresses)
        
            bool secure = false;
            if (address.Scheme == "https")
                secure = true;

            var binding = GetMyCustomBinding(secure);
            var endpoint = serviceHost.AddServiceEndpoint(typeof(IMyService), binding, address);

            endpoint.Behaviors.Add(new MyEndpointBehavior());
        

        return serviceHost;
    

给定的 baseAddresses 数组包括 IIS 绑定到的端点 Uris。对于每个端点,使用自定义绑定将服务绑定到端点。如果端点是“https”,则使用安全绑定;否则,请使用标准绑定。

【讨论】:

以上是关于基于 IIS 绑定将 WCF 端点动态绑定到 HTTPS的主要内容,如果未能解决你的问题,请参考以下文章

WCF 上的一项服务、多个端点、多个绑定。为啥我无法到达我的端点?

将 HTTPS 绑定添加到 IIS 后,具有 Windows 身份验证的 WCF SOAP Web 服务停止工作

WCF 使用凭据和 IIS 以编程方式启用 TLS

WCF 异常:找不到与端点的方案 http 匹配的基地址

WCF 多重绑定 - 错误:没有端点监听

WCF 服务无法将大数组从 DAL 传送到 MVC