我有一个WCF服务,它位于企业级防火墙后面,它同时进行主机名和端口转换,例如:
https://ws.address.com/Service.svc - > https://serv.internal.com:44000/Service.svc
该服务受SSL-128保护,需要客户端证书。
由于无法从防火墙外部访问内部服务器名称,因此我们必须实现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 };
}
}
}
以下是此问题:除非服务托管在默认SSL端口443上的内部计算机上,否则会收到错误:
没有协议绑定与给定地址“https://ws.address.com/Service.svc”匹配。协议绑定在IIS或WAS配置中的站点级别配置。
从修修补补看,如果我们将内部服务器更改为在443上托管服务,或者将防火墙配置为从44000转发到44000,则一切正常。但是,这些不是我们生产环境中的选择。
编辑: 忘记提及,我们尝试使用IWsdlExportExtension来展平WSDL,但这导致了svcutil或VS2008中代理代码生成的严重问题,所以我们取消了这个想法。
有没有人知道这方面的任何方式?我把头发拉出来了!
提前致谢!
答案 0 :(得分:1)
您可能需要显式创建自己的Binding(即ServiceModel.WSHttpBinding)并使用该绑定添加服务端点(.AddServiceEndpoint(..))。
答案 1 :(得分:0)
您是否尝试过将IP端口放在地址中(从问题看起来不像每次都使用的那样):
https://ws.address.com:44000/Service.svc
另一件事是,WCF在该端口上侦听https流量,请参阅:
答案 2 :(得分:0)
您不应该更改工厂中的基地址。编写扩展来修改WSDL。这将是一个“IWsdlExportExtension”,您想要覆盖ExportEndpoint来修改端点地址。这将使您的服务听取正确的基地址。
OR
如果您不想开始使用WSDL扩展程序...将现有代码移动到“CreateServiceHost”方法并刮开自定义主机!这不是很好,但应该有用。
答案 3 :(得分:0)
你没有提到你的主人。 IIS / WAS?如果是这样,您可能需要将外部主机名添加到IIS配置到安全绑定列表。
here is some information on changing the host-name in IIS hosted service
这是命令行:
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"
如果不解决它,我会选择“routeNpingme”并建议您只需要使用指定https端口和名称的绑定正确指定端点。我认为您可以使用现有的绑定选项执行此操作...但您可能需要创建自定义。
答案 4 :(得分:0)
我的猜测是,在IIS中托管服务的网站的网站绑定配置为仅侦听主机名 serv.internal.com ,而不是外部名称 ws.address。 COM 强>
如果使用主机名配置IIS站点绑定,则会针对所有传入URL检查该主机名。该绑定只能处理具有匹配主机名的URL。
防火墙会将请求重定向到内部服务器,但不会更改传入的URL字符串...