我有一个简单的WCF客户端 - >服务器结构,客户端引用服务器的WCF服务。使用X509证书进行身份验证。
我想为我的服务添加一种简单的冗余形式。意思是让多个服务器运行,并让客户端使用一个路由器,如果主服务器已经死了,它将透明地故障转移到备份服务器。
我查看了WCF 4.0路由但是that was no good。
所以剩下的就是自己做。我发现a nice example就是这么做的。
然而,作者根本没有使用任何安全措施。
我尝试通过将以下内容添加到路由器的<client>
绑定配置(我从现有客户端的配置中复制它)来添加消息级安全性:
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
<message clientCredentialType="Certificate" negotiateServiceCredential="false"
algorithmSuite="Default" establishSecurityContext="false" />
</security>
使用这个,我得到了一个
来自我的服务器的未提供客户端证书。指定客户端证书 在ClientCredentials中。
异常。
所以我手动将证书添加到我在路由器代码中创建的频道(此处完整列表):
[ServiceContract(Name = "IntermediateServiceManager")]
public interface IIntermediateServiceContract
{
[OperationContract(Name = "ProcessMessage", Action = "*", ReplyAction = "*")]
Message ProcessMessage(Message message);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, AddressFilterMode = AddressFilterMode.Any)]
public class IntermediateServiceManager : IIntermediateServiceContract
{
public Message ProcessMessage(Message requestMessage)
{
ChannelFactory<IIntermediateServiceContract> factory = new ChannelFactory<IIntermediateServiceContract>("MyEndpoint");
factory.Credentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine,StoreName.My,X509FindType.FindBySubjectName,"mycert.company.com");
IIntermediateServiceContract proxy = factory.CreateChannel();
IClientChannel clientChannel = proxy as IClientChannel;
Message responseMessage = proxy.ProcessMessage(requestMessage);
return responseMessage;
}
}
现在我得到的错误是
名为“安全”和命名空间的多个标头 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' 和角色''发现'。
我已启用WCF诊断功能,并将路由器发送的邮件标头与客户端发送的邮件标头进行比较。实际上,路由器消息有2个安全头。
我假设客户端最初添加了一个(因为它不知道它现在正在对路由器起作用 - 它仍然认为这是实际的服务器),而第二个是路由器。
因此,从逻辑上讲,接下来要做的是禁用我首先添加到路由器配置的安全性(只需将security mode
更改为None
)。
现在我得到的例外是
“收件人”,“http://www.w3.org/2005/08/addressing”必填邮件 部分未签名
我假设这意味着我的路由器已经更改了消息的To
字段,并且由于没有配置安全性 - 路由器没有签名...
所以我猜我有点卡住了。我目前正在考虑的两个选项是:
但是,这样做的缺点是必须更改客户端,我不想这样做。
有什么想法吗?