我有一个简单的 WCF 客户端 -> 服务器结构,其中客户端引用服务器的 WCF 服务。使用 X509 证书完成身份验证。
我想为我的服务添加一种简单形式的冗余。意义——让多台服务器运行,并让客户端使用一个路由器,如果主服务器死机,该路由器将透明地故障转移到备用服务器。
我查看了 WCF 4.0 路由,但这并不好。
所以剩下的就是我自己做。我找到了一个很好的例子。
但是,作者根本没有使用任何安全措施。
我尝试通过将以下内容添加到路由器的<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
字段,并且由于没有配置安全性 - 路由器没有对其进行签名......
所以我想我有点卡住了。我目前正在考虑的两个选项是:
- 以某种方式篡改消息的标头并删除冗余的安全标头。
- 禁用客户端和路由器之间的安全性,只有路由器和服务之间有安全性。
但是,这样做的缺点是必须更改客户端,而我不想这样做。
有任何想法吗?