简体   繁体   English

如何在防火墙后面设置安全的WCF服务?

[英]How do I set up a secure WCF service behind a firewall?

I have a WCF service that is behind an enterprise-class firewall, which is doing both hostname and port translation, eg: 我有一个WCF服务,它位于企业级防火墙后面,它同时进行主机名和端口转换,例如:

https://ws.address.com/Service.svc --> https://serv.internal.com:44000/Service.svc https://ws.address.com/Service.svc - > https://serv.internal.com:44000/Service.svc

The service is secured with SSL-128 and requires a client certificate. 该服务使用SSL-128保护,需要客户端证书。

Because the internal server name is not accessible from outside the firewall, we had to implement a ServiceHostFactory to translate the WSDL and XSD import references that WCF generates: 由于无法从防火墙外部访问内部服务器名称,因此我们必须实现ServiceHostFactory来转换WCF生成的WSDL和XSD导入引用:

public class MyCustomFactory : ServiceHostFactory
    {
        protected override ServiceHost CreateServiceHost(
            Type serviceType, Uri[] baseAddresses)
        {
            MyCustomHost customServiceHost = 
                new MyCustomHost(serviceType, baseAddresses);

            return customServiceHost;
        }

        class MyCustomHost : ServiceHost
        {
            public MyCustomHost(Type serviceType, 
                params Uri[] baseAddresses)
                : base(serviceType, 
                    GetBaseAddresses(serviceType, baseAddresses))
            {                
            }

            protected override void ApplyConfiguration()
            {
                base.ApplyConfiguration();
            }

            private static Uri[] GetBaseAddresses(
                Type serviceType, params Uri[] baseAddresses)
            {
                UriBuilder newBaseAddress = new UriBuilder();
                newBaseAddress.Path = "/" + serviceType.ToString() + 
                    ".svc";

                // from config
                newBaseAddress.Host = 
                    MyCustomSettings.ServiceBaseAddress; 

                if (baseAddresses.Length > 0)
                {
                    newBaseAddress.Scheme = baseAddresses[0].Scheme;
                }

                return new Uri[] { newBaseAddress.Uri };
            }
        }
    }

Here's the problem with this: unless the service is hosted on the internal machine on the default SSL port of 443, we get the error: 这是问题所在:除非服务托管在默认SSL端口443上的内部机器上,否则我们会收到错误:

No protocol binding matches the given address ' https://ws.address.com/Service.svc '. 没有协议绑定与给定地址' https://ws.address.com/Service.svc '匹配。 Protocol bindings are configured at the Site level in IIS or WAS configuration. 协议绑定在IIS或WAS配置中的站点级别配置。

It appears, from tinkering, that if we change the internal server to host the service on 443, or configure the firewall to forward from 44000 to 44000, everything works. 从修修补补看,如果我们将内部服务器更改为在443上托管服务,或者将防火墙配置为从44000转发到44000,则一切正常。 Those aren't options in our production environment, though. 但是,这些不是我们生产环境中的选择。

Edit: Forgot to mention, we tried to use an IWsdlExportExtension to flatten the WSDL, but that caused severe problems with the proxy code generation in svcutil or VS2008, so we scrapped the idea. 编辑:忘记提及,我们尝试使用IWsdlExportExtension来展平WSDL,但这导致了svcutil或VS2008中代理代码生成的严重问题,因此我们废弃了这个想法。

Does anyone know any way around this? 有没有人知道这方面的任何方式? I'm pulling my hair out! 我把头发拉出来!

Thanks in advance! 提前致谢!

You may need to explicitly create your own Binding (ie, ServiceModel.WSHttpBinding) and add a Service Endpoint (.AddServiceEndpoint(..) ) with that binding. 您可能需要显式创建自己的Binding(即ServiceModel.WSHttpBinding)并使用该绑定添加服务端点(.AddServiceEndpoint(..))。

http://msdn.microsoft.com/en-us/library/system.servicemodel.servicehost.addserviceendpoint(VS.85).aspx http://msdn.microsoft.com/en-us/library/system.servicemodel.servicehost.addserviceendpoint(VS.85).aspx

Have you tried putting the ip port in the address (from the question it did not look like it was used everytime): 你有没有尝试将IP端口放在地址中(从它看起来不像每次都使用的问题):

https://ws.address.com:44000/Service.svc

Another thing that it may be is, is WCF listening for https traffic on that port, see: 另一件事是,WCF在该端口上侦听https流量,请参阅:

http://msdn.microsoft.com/en-us/library/ms733768.aspx http://msdn.microsoft.com/en-us/library/ms733768.aspx

You shouldn't change the base addresses in the factory. 您不应该更改工厂中的基址。 Write an extension instead to modify the WSDL. 编写扩展来修改WSDL。 This would be a "IWsdlExportExtension" and you wanna overwrite ExportEndpoint to modify the endpoint addresses. 这将是一个“IWsdlExportExtension”,您想要覆盖ExportEndpoint来修改端点地址。 This will leave your service listening to the correct base address. 这将使您的服务听取正确的基址。

OR 要么

If you don't wan to get started with a WSDL extension...move your existing code into the "CreateServiceHost" method and scratch your custom host! 如果您不想开始使用WSDL扩展...将现有代码移动到“CreateServiceHost”方法并刮开自定义主机! That is not very nice but should work. 这不是很好,但应该工作。

You didn't mention your host. 你没有提到你的主人。 IIS/WAS? IIS / WAS? If so, you may need to add the external host name to IIS config to the secure bindings list. 如果是这样,您可能需要将外部主机名添加到IIS配置到安全绑定列表。

here is some information on changing the host-name in IIS hosted service 以下是有关更改IIS托管服务中的主机名的一些信息

here is the command-line: 这是命令行:

cscript //nologo %systemdrive%\inetpub\adminscripts\adsutil.vbs 
set W3SVC/1/SecureBindings  "10.(internal addr).1:443:ws.address.com"
"127.0.0.1:443:Internal Host name"

If that doesn't take care of it I'd go with "routeNpingme" and suggest you just need to get the endpoints specified correctly, using a binding that specifies your https ports and names. 如果不解决它,我会使用“routeNpingme”并建议您只需要使用指定https端口和名称的绑定正确指定端点。 I think you can do this with existing binding options... but you may need to create a custom. 我认为您可以使用现有的绑定选项执行此操作...但您可能需要创建自定义。

My guess is that the site bindings of the site that hosts your service in IIS are configured to only listen on hostname serv.internal.com instead of the external name ws.address.com . 我的猜测是,在IIS中托管服务的站点的站点绑定被配置为仅侦听主机名serv.internal.com而不是外部名称ws.address.com

If the IIS site bindings are configured with a hostname, that hostname is checked against all incoming URLs. 如果使用主机名配置IIS站点绑定,则会针对所有传入URL检查该主机名。 Only URLs with matching hostname can be processed by that binding. 该绑定只能处理具有匹配主机名的URL。

The firewall will redirect the request to the inside server, but will not alter the incoming URL string... 防火墙会将请求重定向到内部服务器,但不会改变传入的URL字符串......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM