我需要使用轮询技术来通知客户端服务器端的更改。所以我尝试使用DuplexHttpBinding(http://code.msdn.microsoft.com/duplexhttp)。我使用非安全邮件工作正常,但我需要在我的项目中使用消息级安全性(UsernameForCertificate)。好的,我决定将SymmetricSecurityBindingElement添加到绑定集合中:
var securityElement = SecurityBindingElement.CreateUserNameForCertificateBindingElement();
collection.Add(securityElement);
然后问题发生了。如果我们使用消息级安全性,则所有消息都包含带有消息签名的security-headers,如下所示:
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
....
</o:Security>
自定义请求通道发送的自定义轮询消息没有安全标头,因此通过具有消息级安全性的通道发送此消息时发生异常:
System.ServiceModel.Security.MessageSecurityException, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
No signature message parts were specified for messages with the 'http://samples.microsoft.com/duplexhttp/pollingAction' action.
请提供解决方法,在将自定义轮询消息发送到自定义请求通道之前,如何为我的自定义轮询消息添加适当的安全标头。您可以通过之前发布的链接下载源代码,并尝试将其与UsernameForCertificate安全性一起使用以重现该问题。 谢谢。
答案 0 :(得分:2)
几天后&amp;深入调查我找到了解决方案。看来我们应该在创建自定义Channel Facroty&amp;时修改ChannelProtectionRequirements。频道监听器添加加密&amp;我们的自定义消息的签名部分。以下是样本:
private static void ApplyChannelProtectionRequirements(BindingContext context)
{
var cpr = context.BindingParameters.Find<ChannelProtectionRequirements>();
if (cpr != null)
{
XmlQualifiedName qName = new XmlQualifiedName("customHeader", "namespace");
MessagePartSpecification part = new MessagePartSpecification(qName);
cpr.IncomingEncryptionParts.AddParts(part, "incomingAction");
cpr.IncomingSignatureParts.AddParts(part, "incomingAction");
cpr.OutgoingEncryptionParts.AddParts(part, "outgoingAction");
cpr.OutgoingSignatureParts.AddParts(part, "outgoingAction");
}
}