tags:

views:

31

answers:

2

I'm asking the same question here that I've already asked on msdn forums http://social.msdn.microsoft.com/Forums/en-US/netfxnetcom/thread/70f40a4c-8399-4629-9bfc-146524334daf

I'm consuming a (most likely Java based) Web Service with I have absolutely no access to modify. It won't be modified even though I would ask them (it's a nation wide system).

I've written the client with WCF. Here's some code:

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();

After this every request done to the service fails in client side (I can confirm my request is accepted by the service and a sane response is being returned)

I always get the following exception

MessageSecurityException: The security header element 'Timestamp' with the '' id must be signed.

By looking at trace I can see that in the response there really is a timestamp element, but in the security section there is only a signature for body.

Can I somehow make WCF to ingore the fact Timestamp isn't signed?

A: 

You could try using a WCF Message contract. When you have a Message contract you can specify that the items in the header should be signed:

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

[MessageHeader(ProtectionLevel = ProtectionLevel.EncryptAndSign)]
string secret;
Shiraz Bhaiji
This might just be to solution. Now I'm just struggling with the syntax. The xml looks like this:<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><wsu:Created>2010-06-21T06:53:57Z</wsu:Created><wsu:Expires>2010-06-21T06:58:57Z</wsu:Expires></wsu:Timestamp>I don't know how to define this in the custom type.
NiklasN
A: 

I got this sorted out, the answer can be found in here: http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/371184de-5c05-4c70-8899-13536d8f5d16

Main points: add a custom StrippingChannel to the custombinding to strip off the timestamp from the securityheader and configure WCF to not detect replies.

NiklasN