MessageSecurityException:必须对带有'id的安全标头元素'Timestamp'进行签名

时间:2010-06-18 09:40:44

标签: c# wcf wcf-client

我在这里问同样的问题,我已经在msdn论坛上提问http://social.msdn.microsoft.com/Forums/en-US/netfxnetcom/thread/70f40a4c-8399-4629-9bfc-146524334daf

我正在使用(很可能是基于Java的)Web服务,我绝对没有修改权限。即使我会问他们(它是一个全国范围的系统),它也不会被修改。

我用WCF编写了客户端。这是一些代码:

CustomBinding binding = new CustomBinding();
AsymmetricSecurityBindingElement element = SecurityBindingElement.CreateMutualCertificateDuplexBindingElement(MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);
element.AllowSerializedSigningTokenOnReply = true;
element.SetKeyDerivation(false);
element.IncludeTimestamp = true;
element.KeyEntropyMode = SecurityKeyEntropyMode.ClientEntropy;
element.MessageProtectionOrder = System.ServiceModel.Security.MessageProtectionOrder.SignBeforeEncrypt;
element.LocalClientSettings.IdentityVerifier = new CustomIdentityVerifier();
element.SecurityHeaderLayout = SecurityHeaderLayout.Lax;
element.IncludeTimestamp = false;

binding.Elements.Add(element);
binding.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8));
binding.Elements.Add(new HttpsTransportBindingElement());

EndpointAddress address = new EndpointAddress(new Uri("url"));

ChannelFactory<MyPortTypeChannel> factory = new ChannelFactory<MyPortTypeChannel>(binding, address);

ClientCredentials credentials = factory.Endpoint.Behaviors.Find<ClientCredentials>();

credentials.ClientCertificate.Certificate = myClientCert;
credentials.ServiceCertificate.DefaultCertificate = myServiceCert;
credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;

service = factory.CreateChannel();

在此之后,对服务的每个请求都在客户端失败(我可以确认我的请求被服务接受并且正在返回一个合理的响应)

我总是得到以下异常

  

MessageSecurityException:安全性   标题元素'Timestamp'与'''   id必须签名。

通过查看跟踪,我可以看到在响应中确实存在时间戳元素,但在安全性部分中只有身体的签名。

我可以以某种方式让WCF进入时间戳未签名的事实吗?

2 个答案:

答案 0 :(得分:0)

您可以尝试使用WCF消息合约。如果您有邮件合同,则可以指定标题中的项目应签名:

[MessageContract]
public class CustomType
{
[MessageHeader(ProtectionLevel = ProtectionLevel.Sign)]
string name;

[MessageHeader(ProtectionLevel = ProtectionLevel.EncryptAndSign)]
string secret;

答案 1 :(得分:0)

我解决了这个问题,答案可以在这里找到: http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/371184de-5c05-4c70-8899-13536d8f5d16

要点:向自定义绑定添加自定义StrippingChannel,以从安全检查程序中剥离时间戳,并将WCF配置为不检测回复。