none
WCF Client consuming a non-WCF service - MessageSecurityException

    Question

  • I originally asked this question on the .NET Framework Networking and Communication area. However this forum is most likely the right place for this question.

     

    I'm consuming a (most likely Java based) Web Service which I have absolutely no access to modify. I've written the client with WCF4.

    The service uses X.509 certificates for signing diffferent parts of the soap envelope.

    I added the wsdl as a Service Reference in Visual Studio 2010. I modified the generated code a bit by adding

    ProtectionLevel=System.Net.Security.ProtectionLevel.Sign

    to the ServiceContract.

    My request gets accepted by the service and a sane response gets returned. However WCF rejects the response because only the body is signed, timestamp is not.

    The exception message is the following:

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

    Here's the code for the client (I have also tried with XML configuration, no luck either (same exception)).

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

    Tuesday, June 29, 2010 5:42 AM

Answers

  • Hi,

     we got this sorted out with a Microsoft Tech Support person.

     

    The key was to use a custom Stripping channel that stripped off the timestamp from the responses security header. After that WCF had to be configured to not detect replies.

     

    app.config:

    <system.serviceModel>
     <bindings>
      <customBinding>
      <binding name="BankFileServiceCustomBinding">
       <textMessageEncoding messageVersion="Soap11" />
       <security allowSerializedSigningTokenOnReply="true" authenticationMode="MutualCertificate"
       requireDerivedKeys="false" securityHeaderLayout="Lax" includeTimestamp="false" enableUnsecuredResponse="true"
       keyEntropyMode="ClientEntropy" messageProtectionOrder="SignBeforeEncrypt"
       messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
        <localClientSettings detectReplays="false"/>
        <localServiceSettings detectReplays="false"/>
        <secureConversationBootstrap>
         <localClientSettings detectReplays="false"/>
         <localServiceSettings detectReplays="false"/>
        </secureConversationBootstrap>
       </security>
       <StrippingChannel />
       <httpsTransport>
       <extendedProtectionPolicy policyEnforcement="Never" />
       </httpsTransport>
      </binding>
      </customBinding>
     </bindings>
    
      ----
    
      <client>
      <endpoint address="http://localhost:7001/services/CorporateFileService"
      binding="customBinding" bindingConfiguration="BankFileServiceCustomBinding"
      contract="CorporateFileServices.CorporateFileServicePortType"
      name="CorporateFileServiceHttpPort" />
      </client>
    
     ----
    
      <extensions>
       <bindingElementExtensions>
        <add name="StrippingChannel" type="MyAppNamespace.StrippingChannelBindingElementExtensionElement, MyAssembly"/>
       </bindingElementExtensions>
      </extensions>
    </system.serviceModel>

    StrippingChannel:

        class StrippingRequestChannel : IRequestChannel
    	{
    		IRequestChannel _innerChannel = null;
    
    		public StrippingRequestChannel(IRequestChannel innerchannel)
    		{
    			_innerChannel = innerchannel;
    			// hook up event handlers
    			innerchannel.Closed += (sender, e) => { if (Closed != null) Closed(sender, e); };
    			innerchannel.Closing += (sender, e) => { if (Closing != null) Closing(sender, e); };
    			innerchannel.Faulted += (sender, e) => { if (Faulted != null) Faulted(sender, e); };
    			innerchannel.Opened += (sender, e) => { if (Opened != null) Opened(sender, e); };
    			innerchannel.Opening += (sender, e) => { if (Opening != null) Opening(sender, e); };
    		}
    
    		#region IRequestChannel Members
    
    		public IAsyncResult BeginRequest(System.ServiceModel.Channels.Message message, TimeSpan timeout, AsyncCallback callback, object state)
    		{
    			return _innerChannel.BeginRequest(message, timeout, callback, state);
    		}
    
    		public IAsyncResult BeginRequest(System.ServiceModel.Channels.Message message, AsyncCallback callback, object state)
    		{
    			return _innerChannel.BeginRequest(message, callback, state);
    		}
    
    		public System.ServiceModel.Channels.Message EndRequest(IAsyncResult result)
    		{
    			return _innerChannel.EndRequest(result);
    		}
    
    		public EndpointAddress RemoteAddress
    		{
    			get { return _innerChannel.RemoteAddress; }
    		}
    
    		// here must we process the request
    		public System.ServiceModel.Channels.Message Request(System.ServiceModel.Channels.Message message, TimeSpan timeout)
    		{
    			System.ServiceModel.Channels.Message ret = null;
    			// get response first
    			ret = _innerChannel.Request(message, timeout);
    
    			// need to create a copy first
    			MessageBuffer buffer = ret.CreateBufferedCopy(int.MaxValue);
    
    
    			MemoryStream stream = new MemoryStream(1024);
    			buffer.WriteMessage(stream);
    			stream.Position = 0;
    
    			// process XML using XmlDocument and XPathNavigator
    			// note that this is not the most efficient way, but it's the simplest to demonstrate
    			XmlDocument doc = new XmlDocument();
    			doc.Load(stream);
    
    			XPathNavigator n = doc.CreateNavigator();
    
    			//if (n.MoveToFollowing("BinarySecurityToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"))
    			//  n.DeleteSelf();
    
    			//if (n.MoveToFollowing("Signature", "http://www.w3.org/2000/09/xmldsig#"))
    			//  n.DeleteSelf();
    
    			if (n.MoveToFollowing("Timestamp", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"))
    				n.DeleteSelf();
    
    			n.MoveToRoot();
    			XmlReader reader = n.ReadSubtree();
    
    			// create message
    			System.ServiceModel.Channels.Message strippedMessage = System.ServiceModel.Channels.Message.CreateMessage(reader, int.MaxValue, ret.Version);
    			return strippedMessage;
    		}
    
    		public System.ServiceModel.Channels.Message Request(System.ServiceModel.Channels.Message message)
    		{
    			System.ServiceModel.Channels.Message ret = Request(message, new TimeSpan(0, 1, 30));
    			return ret;
    		}
    
    		public Uri Via
    		{
    			get { return _innerChannel.Via; }
    		}
    
    		#endregion
    
    		#region IChannel Members
    
    		public T GetProperty<T>() where T : class
    		{
    			return _innerChannel.GetProperty<T>();
    		}
    
    		#endregion
    
    		#region ICommunicationObject Members
    
    		public void Abort()
    		{
    			_innerChannel.Abort();
    		}
    
    		public IAsyncResult BeginClose(TimeSpan timeout, AsyncCallback callback, object state)
    		{
    			return _innerChannel.BeginClose(timeout, callback, state);
    		}
    
    		public IAsyncResult BeginClose(AsyncCallback callback, object state)
    		{
    			return _innerChannel.BeginClose(callback, state);
    		}
    
    		public IAsyncResult BeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
    		{
    			return _innerChannel.BeginOpen(timeout, callback, state);
    		}
    
    		public IAsyncResult BeginOpen(AsyncCallback callback, object state)
    		{
    			return _innerChannel.BeginOpen(callback, state);
    		}
    
    		public void Close(TimeSpan timeout)
    		{
    			_innerChannel.Close(timeout);
    		}
    
    		public void Close()
    		{
    			_innerChannel.Close();
    		}
    
    		public event EventHandler Closed;
    
    		public event EventHandler Closing;
    
    		public void EndClose(IAsyncResult result)
    		{
    			_innerChannel.EndClose(result);
    		}
    
    		public void EndOpen(IAsyncResult result)
    		{
    			_innerChannel.EndOpen(result);
    		}
    
    		public event EventHandler Faulted;
    
    		public void Open(TimeSpan timeout)
    		{
    			_innerChannel.Open(timeout);
    		}
    
    		public void Open()
    		{
    			_innerChannel.Open();
    		}
    
    		public event EventHandler Opened;
    
    		public event EventHandler Opening;
    
    		public CommunicationState State
    		{
    			get { return _innerChannel.State; }
    		}
    
    		#endregion
    
    		#region IDisposable Members
    
    		public void Dispose()
    		{
    			IDisposable d = _innerChannel as IDisposable;
    			if (d != null) {
    				d.Dispose();
    			}
    		}
    
    		#endregion
    	}
    
    	class StrippingChannelFactory<TChannel> : ChannelFactoryBase<TChannel>
    	{
    		private IChannelFactory<TChannel> innerChannelFactory;
    
    		public IChannelFactory<TChannel> InnerChannelFactory
    		{
    			get { return this.innerChannelFactory; }
    			set { this.innerChannelFactory = value; }
    		}
    
    		public StrippingChannelFactory()
    		{ }
    
    		protected override void OnOpen(TimeSpan timeout)
    		{
    			this.innerChannelFactory.Open(timeout);
    		}
    
    		protected override TChannel OnCreateChannel(EndpointAddress to, Uri via)
    		{
    			TChannel innerchannel = this.innerChannelFactory.CreateChannel(to, via);
    			if (typeof(TChannel) == typeof(IRequestChannel)) {
    				StrippingRequestChannel CachereqCnl = new StrippingRequestChannel((IRequestChannel)innerchannel);
    				return (TChannel)(object)CachereqCnl;
    			}
    			return innerchannel;
    		}
    
    		protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
    		{
    			throw new NotImplementedException();
    		}
    
    		protected override void OnEndOpen(IAsyncResult result)
    		{
    			throw new NotImplementedException();
    		}
    	}
    
    	class StrippingChannelBindingElement : BindingElement
    	{
    		public StrippingChannelBindingElement()
    		{
    		}
    
    		protected StrippingChannelBindingElement(StrippingChannelBindingElement other)
    			: base(other)
    		{
    		}
    
    		public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
    		{
    			StrippingChannelFactory<TChannel> Cachecf = new StrippingChannelFactory<TChannel>();
    			Cachecf.InnerChannelFactory = context.BuildInnerChannelFactory<TChannel>();
    			return Cachecf;
    		}
    
    		public override BindingElement Clone()
    		{
    			StrippingChannelBindingElement other = new StrippingChannelBindingElement(this);
    			return other;
    		}
    
    		public override T GetProperty<T>(BindingContext context)
    		{
    			return context.GetInnerProperty<T>();
    		}
    	}
    
    	class StrippingChannelBindingElementExtensionElement : BindingElementExtensionElement
    	{
    		public override Type BindingElementType
    		{
    			get { return typeof(StrippingChannelBindingElement); }
    		}
    
    		protected override BindingElement CreateBindingElement()
    		{
    			return new StrippingChannelBindingElement();
    		}
    	}

    • Marked as answer by Tomi Nokkala Wednesday, July 07, 2010 6:48 AM
    Wednesday, July 07, 2010 6:47 AM

All replies

  • I have already tried playing around with MessageContracts, but either my syntax is wrong, or then it is not the answer to my problem..
    Tuesday, June 29, 2010 11:55 AM
  • Hello,

    there is one more central place to deal with signed and encrypted parts. It is ChannelProtectionRequirements. I know that you can add additional parts to sign or encrypt them but I'm not sure if there is also possibility to remove parts. Example of using ChannelProtectionRequirements to sign and encrypt additional headers:

    http://social.msdn.microsoft.com/Forums/en/wcf/thread/98180643-7082-41fd-96a9-0ea6bb0754ac

    Best regards,
    Ladislav

    Tuesday, June 29, 2010 12:14 PM
  • Hi,

    thanks for your suggestion. I however didn't succeed with similar code to the thread you linked.

    Inspired from your suggestion I googled a bit and stumbled upon this blog post:

    http://blogs.msdn.com/b/drnick/archive/2007/01/19/securing-custom-headers-version-2.aspx

    I tried with that method, but it seems this only affects the service, not client. Here's the code I tried:

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    	OperationDescription operation = endpoint.Contract.Operations.Find("downloadFileList");
    	MessageDescription message = operation.Messages.Find("*");
    	MessageHeaderDescription header = message.Headers[new XmlQualifiedName("Timestamp", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd")];
    	header.ProtectionLevel = ProtectionLevel.None;
    }
    I'm still getting the same Exception.

    Tuesday, June 29, 2010 8:36 PM
  • If you do not send a timestamp will  the server accept it? If so, try setting includeTimestamp to false.

    If the server requires timestamp but it doe not have to be sign set as before and manually add the timestamp in a custom encoder.


    http://webservices20.blogspot.com/
    WCF Security, Performance And Testing Blog
    • Marked as answer by Bin-ze Zhao Tuesday, July 06, 2010 10:04 AM
    • Unmarked as answer by Tomi Nokkala Tuesday, July 06, 2010 7:20 PM
    Saturday, July 03, 2010 5:58 PM
  • Hi,

    Does this thread help:

    http://social.msdn.microsoft.com/forums/en-US/wcf/thread/4bba1994-db87-4eaf-a876-840101a9b9f3/

    <customBinding>
    
     <binding name="MutualCertificateBinding">
    
      <security authenticationMode="MutualCertificate" securityHeaderLayout="Lax"/>
    
      <httpTransport/>
    
     </binding>
    
    </customBinding>
    
    

    Thanks

    Binze


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Wednesday, July 07, 2010 4:42 AM
  • Hi,

     we got this sorted out with a Microsoft Tech Support person.

     

    The key was to use a custom Stripping channel that stripped off the timestamp from the responses security header. After that WCF had to be configured to not detect replies.

     

    app.config:

    <system.serviceModel>
     <bindings>
      <customBinding>
      <binding name="BankFileServiceCustomBinding">
       <textMessageEncoding messageVersion="Soap11" />
       <security allowSerializedSigningTokenOnReply="true" authenticationMode="MutualCertificate"
       requireDerivedKeys="false" securityHeaderLayout="Lax" includeTimestamp="false" enableUnsecuredResponse="true"
       keyEntropyMode="ClientEntropy" messageProtectionOrder="SignBeforeEncrypt"
       messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
        <localClientSettings detectReplays="false"/>
        <localServiceSettings detectReplays="false"/>
        <secureConversationBootstrap>
         <localClientSettings detectReplays="false"/>
         <localServiceSettings detectReplays="false"/>
        </secureConversationBootstrap>
       </security>
       <StrippingChannel />
       <httpsTransport>
       <extendedProtectionPolicy policyEnforcement="Never" />
       </httpsTransport>
      </binding>
      </customBinding>
     </bindings>
    
      ----
    
      <client>
      <endpoint address="http://localhost:7001/services/CorporateFileService"
      binding="customBinding" bindingConfiguration="BankFileServiceCustomBinding"
      contract="CorporateFileServices.CorporateFileServicePortType"
      name="CorporateFileServiceHttpPort" />
      </client>
    
     ----
    
      <extensions>
       <bindingElementExtensions>
        <add name="StrippingChannel" type="MyAppNamespace.StrippingChannelBindingElementExtensionElement, MyAssembly"/>
       </bindingElementExtensions>
      </extensions>
    </system.serviceModel>

    StrippingChannel:

        class StrippingRequestChannel : IRequestChannel
    	{
    		IRequestChannel _innerChannel = null;
    
    		public StrippingRequestChannel(IRequestChannel innerchannel)
    		{
    			_innerChannel = innerchannel;
    			// hook up event handlers
    			innerchannel.Closed += (sender, e) => { if (Closed != null) Closed(sender, e); };
    			innerchannel.Closing += (sender, e) => { if (Closing != null) Closing(sender, e); };
    			innerchannel.Faulted += (sender, e) => { if (Faulted != null) Faulted(sender, e); };
    			innerchannel.Opened += (sender, e) => { if (Opened != null) Opened(sender, e); };
    			innerchannel.Opening += (sender, e) => { if (Opening != null) Opening(sender, e); };
    		}
    
    		#region IRequestChannel Members
    
    		public IAsyncResult BeginRequest(System.ServiceModel.Channels.Message message, TimeSpan timeout, AsyncCallback callback, object state)
    		{
    			return _innerChannel.BeginRequest(message, timeout, callback, state);
    		}
    
    		public IAsyncResult BeginRequest(System.ServiceModel.Channels.Message message, AsyncCallback callback, object state)
    		{
    			return _innerChannel.BeginRequest(message, callback, state);
    		}
    
    		public System.ServiceModel.Channels.Message EndRequest(IAsyncResult result)
    		{
    			return _innerChannel.EndRequest(result);
    		}
    
    		public EndpointAddress RemoteAddress
    		{
    			get { return _innerChannel.RemoteAddress; }
    		}
    
    		// here must we process the request
    		public System.ServiceModel.Channels.Message Request(System.ServiceModel.Channels.Message message, TimeSpan timeout)
    		{
    			System.ServiceModel.Channels.Message ret = null;
    			// get response first
    			ret = _innerChannel.Request(message, timeout);
    
    			// need to create a copy first
    			MessageBuffer buffer = ret.CreateBufferedCopy(int.MaxValue);
    
    
    			MemoryStream stream = new MemoryStream(1024);
    			buffer.WriteMessage(stream);
    			stream.Position = 0;
    
    			// process XML using XmlDocument and XPathNavigator
    			// note that this is not the most efficient way, but it's the simplest to demonstrate
    			XmlDocument doc = new XmlDocument();
    			doc.Load(stream);
    
    			XPathNavigator n = doc.CreateNavigator();
    
    			//if (n.MoveToFollowing("BinarySecurityToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"))
    			//  n.DeleteSelf();
    
    			//if (n.MoveToFollowing("Signature", "http://www.w3.org/2000/09/xmldsig#"))
    			//  n.DeleteSelf();
    
    			if (n.MoveToFollowing("Timestamp", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"))
    				n.DeleteSelf();
    
    			n.MoveToRoot();
    			XmlReader reader = n.ReadSubtree();
    
    			// create message
    			System.ServiceModel.Channels.Message strippedMessage = System.ServiceModel.Channels.Message.CreateMessage(reader, int.MaxValue, ret.Version);
    			return strippedMessage;
    		}
    
    		public System.ServiceModel.Channels.Message Request(System.ServiceModel.Channels.Message message)
    		{
    			System.ServiceModel.Channels.Message ret = Request(message, new TimeSpan(0, 1, 30));
    			return ret;
    		}
    
    		public Uri Via
    		{
    			get { return _innerChannel.Via; }
    		}
    
    		#endregion
    
    		#region IChannel Members
    
    		public T GetProperty<T>() where T : class
    		{
    			return _innerChannel.GetProperty<T>();
    		}
    
    		#endregion
    
    		#region ICommunicationObject Members
    
    		public void Abort()
    		{
    			_innerChannel.Abort();
    		}
    
    		public IAsyncResult BeginClose(TimeSpan timeout, AsyncCallback callback, object state)
    		{
    			return _innerChannel.BeginClose(timeout, callback, state);
    		}
    
    		public IAsyncResult BeginClose(AsyncCallback callback, object state)
    		{
    			return _innerChannel.BeginClose(callback, state);
    		}
    
    		public IAsyncResult BeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
    		{
    			return _innerChannel.BeginOpen(timeout, callback, state);
    		}
    
    		public IAsyncResult BeginOpen(AsyncCallback callback, object state)
    		{
    			return _innerChannel.BeginOpen(callback, state);
    		}
    
    		public void Close(TimeSpan timeout)
    		{
    			_innerChannel.Close(timeout);
    		}
    
    		public void Close()
    		{
    			_innerChannel.Close();
    		}
    
    		public event EventHandler Closed;
    
    		public event EventHandler Closing;
    
    		public void EndClose(IAsyncResult result)
    		{
    			_innerChannel.EndClose(result);
    		}
    
    		public void EndOpen(IAsyncResult result)
    		{
    			_innerChannel.EndOpen(result);
    		}
    
    		public event EventHandler Faulted;
    
    		public void Open(TimeSpan timeout)
    		{
    			_innerChannel.Open(timeout);
    		}
    
    		public void Open()
    		{
    			_innerChannel.Open();
    		}
    
    		public event EventHandler Opened;
    
    		public event EventHandler Opening;
    
    		public CommunicationState State
    		{
    			get { return _innerChannel.State; }
    		}
    
    		#endregion
    
    		#region IDisposable Members
    
    		public void Dispose()
    		{
    			IDisposable d = _innerChannel as IDisposable;
    			if (d != null) {
    				d.Dispose();
    			}
    		}
    
    		#endregion
    	}
    
    	class StrippingChannelFactory<TChannel> : ChannelFactoryBase<TChannel>
    	{
    		private IChannelFactory<TChannel> innerChannelFactory;
    
    		public IChannelFactory<TChannel> InnerChannelFactory
    		{
    			get { return this.innerChannelFactory; }
    			set { this.innerChannelFactory = value; }
    		}
    
    		public StrippingChannelFactory()
    		{ }
    
    		protected override void OnOpen(TimeSpan timeout)
    		{
    			this.innerChannelFactory.Open(timeout);
    		}
    
    		protected override TChannel OnCreateChannel(EndpointAddress to, Uri via)
    		{
    			TChannel innerchannel = this.innerChannelFactory.CreateChannel(to, via);
    			if (typeof(TChannel) == typeof(IRequestChannel)) {
    				StrippingRequestChannel CachereqCnl = new StrippingRequestChannel((IRequestChannel)innerchannel);
    				return (TChannel)(object)CachereqCnl;
    			}
    			return innerchannel;
    		}
    
    		protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
    		{
    			throw new NotImplementedException();
    		}
    
    		protected override void OnEndOpen(IAsyncResult result)
    		{
    			throw new NotImplementedException();
    		}
    	}
    
    	class StrippingChannelBindingElement : BindingElement
    	{
    		public StrippingChannelBindingElement()
    		{
    		}
    
    		protected StrippingChannelBindingElement(StrippingChannelBindingElement other)
    			: base(other)
    		{
    		}
    
    		public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
    		{
    			StrippingChannelFactory<TChannel> Cachecf = new StrippingChannelFactory<TChannel>();
    			Cachecf.InnerChannelFactory = context.BuildInnerChannelFactory<TChannel>();
    			return Cachecf;
    		}
    
    		public override BindingElement Clone()
    		{
    			StrippingChannelBindingElement other = new StrippingChannelBindingElement(this);
    			return other;
    		}
    
    		public override T GetProperty<T>(BindingContext context)
    		{
    			return context.GetInnerProperty<T>();
    		}
    	}
    
    	class StrippingChannelBindingElementExtensionElement : BindingElementExtensionElement
    	{
    		public override Type BindingElementType
    		{
    			get { return typeof(StrippingChannelBindingElement); }
    		}
    
    		protected override BindingElement CreateBindingElement()
    		{
    			return new StrippingChannelBindingElement();
    		}
    	}

    • Marked as answer by Tomi Nokkala Wednesday, July 07, 2010 6:48 AM
    Wednesday, July 07, 2010 6:47 AM
  • I have same problem. ... Java service that requires X.509 certificates for signing diffferent parts of the soap envelope and Java service is not sign Timestamp of the return message.

    When I tried to stripped off the timestamp using above code i got error:

    Message security verification failed.

    Is there any way to handle reply message (using wcf) where response messages timestamp is not digitally signed? 

    Friday, November 05, 2010 12:36 PM
  • Hi,

    IIRC you need to specify AllowUnsecuredResponse=true in your custom binding.

     

    Regards,

    Niklas

    Sunday, January 02, 2011 6:23 PM
  • Hi Niklas,

     

    I am trying to use the above code to check the response.

    I am using VS 2008 and  WCF 3.5. I can't find the attribute "enableUnsecuredResponse" for custom binding. Is there an equivalent attribute in VS 2008?

     

    Thanks

    Smt888

     

    Thursday, January 20, 2011 2:54 PM
  • Hi,

    I had installed a trial version of VS2010 professional, SP1 and the above configuration doesn't work. It is complaining that the attribute "enableUnsecuredResponse" is not valid. Also I cannot include "bindingElementExtensions" named "StrippingChannel" in my custom binding. I had the "bindingElementExtensions" defined.

    Any suggestions?

     

    smt888

    Friday, January 28, 2011 2:24 PM
  • Hi,

    you need the hotfix for .NET 3.5 or then use .NET 4.0.

     

    Here's the link to the hotfix

    http://support.microsoft.com/kb/971493

     

    Niklas

    Thursday, February 17, 2011 12:03 PM
  • Hi!

    I'm trying to migrate a WSE3 project to WCF. I've customized a lot of things: CustomBinding, Custom Stripped Message by ClientMessageInspector,

    DispatchMessageInspector, Custom MessageHeaders, and nothing seems to work, actually I'm stucked, the solution has eludes me for 3 weeks.

    This is my scenario: I've got a client app (WCF) that has to call a web service (WSE3) using digital certificate signature, using MutualCertificate, WS-

    Security 1.0 and SOAP 1.1 over https.

    In VS2005 / Framework 2.0 / WSE3, this is my configuration:

    Web.Config

    <?xml version="1.0"?>
    <configuration>
      <configSections>
        <section name="microsoft.web.services3" type="Microsoft.Web.Services3.Configuration.WebServicesConfiguration, Microsoft.Web.Services3, Version=3.0.0.0,

    Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral,

    PublicKeyToken=b77a5c561934e089" >
          <section name="demoWSE.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral,

    PublicKeyToken=b77a5c561934e089" requirePermission="false" />
        </sectionGroup>
      </configSections>
      <appSettings/>
      <connectionStrings/>
      <system.web>
        <compilation debug="true">
          <assemblies>
            <add assembly="Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
          </assemblies>
        </compilation>
        <authentication mode="Windows" />
        <webServices>
          <soapExtensionImporterTypes>
            <add type="Microsoft.Web.Services3.Description.WseExtensionImporter, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral,

    PublicKeyToken=31bf3856ad364e35"/>
          </soapExtensionImporterTypes>
          <soapServerProtocolFactory type="Microsoft.Web.Services3.WseProtocolFactory, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral,

    PublicKeyToken=31bf3856ad364e35"/>
        </webServices>
      </system.web>
      <microsoft.web.services3>
        <security>
          <x509 allowTestRoot="true" revocationMode="NoCheck"/>
        </security>
        <policy fileName="wse3policyCache.config"/>
      </microsoft.web.services3>
      <applicationSettings>
        <demoWSE.Properties.Settings>
          <setting name="demoWSE_ServiceImpl" serializeAs="String">
            <value>https://server//service.asmx</value>
          </setting>
        </demoWSE.Properties.Settings>
      </applicationSettings>
    </configuration>

    This is my wse3policyCache.config:

    <policies xmlns="http://schemas.microsoft.com/wse/2005/06/policy">
      <extensions>
        <extension name="mutualCertificate11Security" type="Microsoft.Web.Services3.Design.MutualCertificate11Assertion, Microsoft.Web.Services3,

    Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
        <extension name="x509" type="Microsoft.Web.Services3.Design.X509TokenProvider, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral,

    PublicKeyToken=31bf3856ad364e35" />
        <extension name="requireActionHeader" type="Microsoft.Web.Services3.Design.RequireActionHeaderAssertion, Microsoft.Web.Services3, Version=3.0.0.0,

    Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
        <extension name="mutualCertificate10Security" type="Microsoft.Web.Services3.Design.MutualCertificate10Assertion, Microsoft.Web.Services3,

    Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      </extensions>
      <policy name="MyClientPolicy">
        <mutualCertificate10Security
          establishSecurityContext="false"
          renewExpiredSecurityContext="false"
          requireSignatureConfirmation="false"
          messageProtectionOrder="SignBeforeEncrypt"
          requireDerivedKeys="false"
          ttlInSeconds="0">
          <clientToken>
            <x509 storeLocation="LocalMachine"
                  storeName="Root"
                  findValue="ClientCertificate"
                  findType="FindBySubjectName" />
          </clientToken>
          <serviceToken>
            <x509 storeLocation="LocalMachine"
                  storeName="Root"
                  findValue="ServerCertificate"
                  findType="FindBySubjectName" />
          </serviceToken>
          <protection>
            <request signatureOptions="IncludeSoapBody" encryptBody="false" />
            <response signatureOptions="IncludeSoapBody" encryptBody="false" />
            <fault signatureOptions="IncludeSoapBody" encryptBody="false" />
          </protection>
        </mutualCertificate10Security>
        <requireActionHeader />
      </policy>
    </policies>

    And works!!! This is my request:

    <?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-

    open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-

    1.0.xsd">
     <soap:Header>
      <wsa:Action>http://server/service/getBankList</wsa:Action>
      <wsa:MessageID>urn:uuid:e3929fad-9dd4-4e8a-bdfa-a6c68f65ab1e</wsa:MessageID>
      <wsa:ReplyTo>
       <wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>
      </wsa:ReplyTo>
      <wsa:To>https://server/service.asmx</wsa:To>
      <wsse:Security soap:mustUnderstand="1">
       <wsu:Timestamp wsu:Id="Timestamp-42242ba3-fec1-40f0-a486-3cadc9a1f804">
        <wsu:Created>2012-01-24T13:43:38Z</wsu:Created>
        <wsu:Expires>2012-01-24T13:43:38Z</wsu:Expires>
       </wsu:Timestamp>
       <wsse:BinarySecurityToken ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"

    EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" xmlns:wsu="http://docs.oasis-

    open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-f7447799-bb57-41ab-b888-

    87f8bac3b599">MIIGRTCCBS2gAwIBAgIQSzcFWBHvDSdO2S1bm7FixTANBgkqhkiG9w0BAQUFADCCAU8xcjBwBgNVBAkTaUNSIDcgTiAyNi0yMCBQIDE4IC0gaHR0cDovL3d3dy5jZXJ0aWNhbWFyYS5jb20

    gLSBURUxTIDU3LTEtNzQ0MjcyNyA1Ny0wMTgwMDAxODE1MzEgLSBpbmZvQGNlcnRpY2FtYXJhLmNvbTEPMA0GA1UEBxMGQk9HT1RBMRkwFwYDVQQIExBESVNUUklUTyBDQVBJVEFMMQswCQYDVQQGEwJDTzEr

    MCkGA1UECxMiQ0VSVElDQU1BUkEgUy5BLiAtIE5JVCA4MzAwODQ0MzMgNzFFMEMGA1UEChM8Q0VSVElDQU1BUkEgUy5BLiAtIFNPQ0lFREFEIENBTUVSQUwgREUgQ0VSVElGSUNBQ0lPTiBESUdJVEFMMSwwK

    gYDVQQDEyNBQyBJTlRFUk1FRElBIERFTU8gQ0VSVElDQU1BUkEgUy5BLjAeFw0xMTEyMDIxOTU2MTFaFw0xMjEyMDIxOTU2MTFaMIHBMQswCQYDVQQGEwJDTzERMA8GA1UEBxMITWVkZWxsaW4xHjAcBgNVBA

    oTFUZhY3RvcmluZyBCYW5jb2xvbWJpYTEeMBwGA1UEAxMVRmFjdG9yaW5nIEJhbmNvbG9tYmlhMS8wLQYJKoZIhvcNAQkBFiBlYW5ndWxvQGZhY3RvcmluZ2JhbmNvbG9tYmlhLmNvbTEaMBgGCisGAQQBgbV

    jAgMTCjg5MDkyNjI4MzExEjAQBgNVBAgTCUFudGlvcXVpYTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANZguRXVtGNqevHYAxkuC6kyL2ZgJgYkznBlRVxVpr1xGuN1zGHbZO3Fp1ZHoMc3CAZ2

    eWcOectIW/OrgogtI8u

    +1GMdzXUf8wisMhcZsYKPg05ubLn/JUsCHsd59BVuAGnEtjkKFf0KlDx9vF0CNXVFjuqVKTd/HNBCvBH/fYvb9nT6CaZmfZmC7OPaOftccvhGy065cbw/ZDVlS8sxWobaLAL7EKBzvq7+RzealjBs4sVuPXlL

    Z5XVeYGMTUnJmFkTE3wYs+dxWGlbtSlhNStFWjEbqA9V4I4TUzpzMBpPjeUnsV

    +8cZkvgLWF802iyPjEGOfVFmBP8LxOA9nFNfUCAwEAAaOCAaYwggGiMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgP4MCcGA1UdJQQgMB4GCCsGAQUFBwMCBggrBgEFBQcDBAYIKwYBBQUHAwEwEQYJYIZ

    IAYb4QgEBBAQDAgWgMB0GA1UdDgQWBBRpc5LVNUz4/5yuJkxV0WlEgqk/MjAfBgNVHSMEGDAWgBRDOtcINJxKna9GSoXvXxVrYY27aDCBkAYDVR0gBIGIMIGFMIGCBgsrBgEEAYG1YzIBUDBzMCsGCCsGAQUF

    BwIBFh9odHRwOi8vd3d3LmNlcnRpY2FtYXJhLmNvbS9kcGMvMEQGCCsGAQUFBwICMDgaNkNlcnRpZmljYWRvIGVtaXRpZG8gcG9yIGxhIENBIERlbW8gZGUgQ2VydGljYW1hcmEgUy5BLjA7BggrBgEFBQcBA

    QQvMC0wKwYIKwYBBQUHMAGGH2h0dHA6Ly9vY3NwZGVtby5jZXJ0aWNhbWFyYS5jb20wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL3d3dy5jZXJ0aWNhbWFyYS5jb20vY2FkZW1vLmNybDANBgkqhkiG9w0BAQ

    UFAAOCAQEAle8CJec9+X5bwkY+mpEzs9qlx7zzJCXBqVEER5FGU0FbYrB4zQ/rSbcNw0dk7+ZXrHRDAHgWMbeL7JINVvpLN5RhYwzi

    +2ZED3JOd2q8Vz2U1llEGVtaMlChnISWvjuji0ACdN6dDgugzHKmPX3M4kSrfnzJluDsxAn00K16QEbSNWbhnbB/XzsAvdf652aWTc7+VyKEKewduWTVlSrJmGp28vqgsji5qyMjvgimNgNjsAjPc77g01kom

    hqnCS2YzCctl/SALp5lFbqaOWIQXbvA1YDSV77nkq9SCCjt/qtSCX6Dz+oBtDTaN5prwySAqg1TL82Y4g97pK1y5QVFSA==</wsse:BinarySecurityToken>
       <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo>
         <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" />
         <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
         <Reference URI="#Id-1f546175-d557-45fb-8e37-ddf14b51c1af">
          <Transforms>
           <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
          </Transforms>
          <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
          <DigestValue>6nCKPgI2dX8UiHgn9Q9nQQFBIjM=</DigestValue>
         </Reference>
        </SignedInfo>
        <SignatureValue>D9HVZrzglTRXaLTvN8K2SX6OTxZQszUL0pl1D4veEEg061WqNbp

    +L9hPcagIiomcgOX2zwu9SdgUeXF3DM46j0ip/VgWH7ReYSZyQ3vL7EMG0R3mRVTOn5If2ZByJzqdGEza/0kJmsvkb31i6INSAns3sFO1kTEQCAoDExOjSgzjwV52QyUWTjJ6hYpzkTBPYpQVgNHrhFdqVXyt

    GAOhbxZe1VvEL9aYr1d3jzOVjHkcjtYUBhrrfgwI1lHp12BzfSkCTxWNy6UOmjMd7iWLZqvbA2YmFNZ/xZ7mzsSz7z13deY8bODQ5cFCmQeAlycLtqHCme6WKo8N15+Wyi0COw==</SignatureValue>
        <KeyInfo>
         <wsse:SecurityTokenReference>
          <wsse:Reference URI="#SecurityToken-f7447799-bb57-41ab-b888-87f8bac3b599" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-

    token-profile-1.0#X509v3" />
         </wsse:SecurityTokenReference>
        </KeyInfo>
       </Signature>
      </wsse:Security>
     </soap:Header>
     <soap:Body wsu:Id="Id-1f546175-d557-45fb-8e37-ddf14b51c1af">
      <getBankList xmlns="http://www.uc-council.org/smp/schemas/eanucc">
       <getBankListInformation>
        <entityCode>123456</entityCode>
       </getBankListInformation>
      </getBankList>
     </soap:Body>
    </soap:Envelope>

    And this is the response:

    <?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-

    open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-

    1.0.xsd">
     <soap:Header>
      <messageHeader xmlns="http://www.uc-council.org/smp/schemas/eanucc">
       <to>
        <gln>123456</gln>
       </to>
       <from>
        <gln>7890</gln>
       </from>
       <representingParty>
        <gln>111111</gln>
       </representingParty>
      </messageHeader>
      <wsa:Action>http://server/service/getBankListResponse</wsa:Action>
      <wsa:MessageID>urn:uuid:2e2f5da5-a399-4882-a5c6-1784719adfb1</wsa:MessageID>
      <wsa:RelatesTo>urn:uuid:e3929fad-9dd4-4e8a-bdfa-a6c68f65ab1e</wsa:RelatesTo>
      <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
      <wsse:Security soap:mustUnderstand="1">
       <wsu:Timestamp wsu:Id="Timestamp-c4025538-fcd7-4c56-bcbc-128040b0fd42">
        <wsu:Created>2012-01-24T13:46:34Z</wsu:Created>
        <wsu:Expires>2012-01-24T13:51:34Z</wsu:Expires>
       </wsu:Timestamp>
       <wsse:BinarySecurityToken ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"

    EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" xmlns:wsu="http://docs.oasis-

    open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-f30c2097-cb2b-4eca-9102-

    e2a121b780c0">MIIGLDCCBRSgAwIBAgIQfr4rMVquxrpNzXN2eEDzvzANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UEBhMCQ08xRzBFBgNVBAoMPlNvY2llZGFkIENhbWVyYWwgZGUgQ2VydGlmaWNhY2nDs24

    gRGlnaXRhbCAtIENlcnRpY8OhbWFyYSBTLkEuMSkwJwYDVQQDDCBBQyBTdWJvcmRpbmFkYSBDZXJ0aWPDoW1hcmEgUy5BLjAeFw0xMTA1MTMxODA3NTBaFw0xMjA1MTMxODA3NTBaMIGMMQswCQYDVQQGEwJD

    TzEhMB8GA1UECAwYQm9nb3RhIERDIFBTRSBEZXNhcnJvbGxvMQ8wDQYDVQQHDAZCb2dvdGExGjAYBgNVBAoMEUFDSCBDb2xvbWJpYSBTLkEuMREwDwYDVQQLDAhTaXN0ZW1hczEaMBgGA1UEAwwRQUNIIENvb

    G9tYmlhIFMuQS4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0VX6lh4zB8KtR43UPy9adwWUTZDLLamrvAfyRQ9IFi9Iw40vXZvgjH

    +hfjlu3IffoKzAVZ6Upb5yPIbiGkxcmSleNP/b9CfMyuiRP8Tnpb94yIB54tEbu34zNTdyKnqfbXlc5nfguNyPILzzLh

    +uNcmSCwhOuqGyD3nQdaeQCLJDiz6Tvr87HRubQN4pPp8O9mpEQTtytvnMmcfkjY/97PsamVi7+pG20IQV96p

    +f3sz5+fKW9bn/OrtP8DCaPsJ3VO1o7juX5HUwDaFN2RMxyFAR1UeaEur7V26vNlR4/uwthy9+86TVFf9Z4861FsaqiW1HohsXMoEt

    +wZ93PQdAgMBAAGjggKRMIICjTAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwID+DAnBgNVHSUEIDAeBggrBgEFBQcDAgYIKwYBBQUHAwQGCCsGAQUFBwMBMBEGCWCGSAGG

    +EIBAQQEAwIFoDAdBgNVHQ4EFgQUbcB5Zk1am7tqoLI9kksI

    +znnAuwwHwYDVR0jBBgwFoAUz8POxxPBHLNpqsU1X0+kQdOiuI8wgecGA1UdIASB3zCB3DCBmQYLKwYBBAGBtWMyAVEwgYkwKwYIKwYBBQUHAgEWH2h0dHA6Ly93d3cuY2VydGljYW1hcmEuY29tL2RwYy8wW

    gYIKwYBBQUHAgIwThpMTGltaXRhY2lvbmVzIGRlIGdhcmFudO1hcyBkZSBlc3RlIGNlcnRpZmljYWRvIHNlIHB1ZWRlbiBlbmNvbnRyYXIgZW4gbGEgRFBDLjA

    +BgsrBgEEAYG1YwoKATAvMC0GCCsGAQUFBwICMCEaH0Rpc3Bvc2l0aXZvIGRlIGhhcmR3YXJlIChUb2tlbikwNwYIKwYBBQUHAQEEKzApMCcGCCsGAQUFBzABhhtodHRwOi8vb2NzcC5jZXJ0aWNhbWFyYS5j

    b20wgc0GA1UdHwSBxTCBwjCBv6CBvKCBuYZZaHR0cDovL3d3dy5jZXJ0aWNhbWFyYS5jb20vcmVwb3NpdG9yaW9yZXZvY2FjaW9uZXMvYWNfc3Vib3JkaW5hZGFfY2VydGljYW1hcmEuY3JsP2NybD1jcmyGX

    Gh0dHA6Ly9taXJyb3IuY2VydGljYW1hcmEuY29tL3JlcG9zaXRvcmlvcmV2b2NhY2lvbmVzL2FjX3N1Ym9yZGluYWRhX2NlcnRpY2FtYXJhLmNybD9jcmw9Y3JsMA0GCSqGSIb3DQEBBQUAA4IBAQAT12CFQL

    MfhtKaHYbJFjIl5V0ke2cDNeMZH0t0COKVZzFGTs/9z/kVlks1IMfvmvw4/4IJQUtiWrSPSTp41FlZCiPqwrQDimKEYP/gpnX8Re9qkilxsfWrizrMAOHguTovzkruDfDTveFQ/vA3jLI8EuESV9pZ4JTmx24

    WTWVaqfHD4MWgN5WJQI980QjinWBCKm4VnL

    +2oG6pBgS9/PWrNr3NZEeImNsTs74EbZOUJKNUYTCDxbddP9KAUMy4JwtlV8gCYLsndhLZxcgkWYWDQD6DzrTggxG70VpNX3WUY6560nqXH8vwAYyYrKq9TEnyyTOPXzgP/KLebWGwQlHX</wsse:BinarySe

    curityToken>
       <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo>
         <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" />
         <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
         <Reference URI="#Id-7eb387cf-2693-4c5d-afa3-ada214df5cb5">
          <Transforms>
           <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
          </Transforms>
          <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
          <DigestValue>d2im4gPUiJeae9k5wXx9g0jM07A=</DigestValue>
         </Reference>
        </SignedInfo>
        <SignatureValue>KVZXSJS9aly/HlGq/n6EYE+PsAFtoGAUgc/LKmIucsR3dP7gbDMCO2C8ZUaieX1G/oCs75whFH8e3Ae8ZwJVhVxfjfv96DgI1g/M9b79Hgx

    +lErmlYRtmQhZ3vA/fQCEfP2H1ErRLz6cxdjd0IwKHUPmpEmtK2pnT9KUMkzVRntoD0bUy+/rlmLw5tGWQ7wjDTt1r7s9UFTxcVOS7ohfxckG/QoK7mfUk1+KusbmLfrYvBTKvjTzb3UsX7d/kNrZF

    +SIts0n9jKdt9nCn0KQxC/a/D1h+k0ALs9ZDdApn9zMaCsVu/UsbtpKikxi3NX/XgI+evUij8l3nb2QlUU2dw==</SignatureValue>
        <KeyInfo>
         <wsse:SecurityTokenReference>
          <wsse:Reference URI="#SecurityToken-f30c2097-cb2b-4eca-9102-e2a121b780c0" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-

    token-profile-1.0#X509v3" />
         </wsse:SecurityTokenReference>
        </KeyInfo>
       </Signature>
      </wsse:Security>
     </soap:Header>
     <soap:Body wsu:Id="Id-7eb387cf-2693-4c5d-afa3-ada214df5cb5">
      <getBankListResponse xmlns="http://www.uc-council.org/smp/schemas/eanucc">
       <getBankListResponseInformation>
        <financialInstitutionCode>123</financialInstitutionCode>
        <financialInstitutionName>Bank1</financialInstitutionName>
       </getBankListResponseInformation>
       <getBankListResponseInformation>
        <financialInstitutionCode>456</financialInstitutionCode>
        <financialInstitutionName>Bank2</financialInstitutionName>
       </getBankListResponseInformation>
      </getBankListResponse>
     </soap:Body>
    </soap:Envelope>

    Ok. It works... so, I have to create a similar call in VS2010 / WCF / Framework 4.0

    This is my Web.Config:

    <?xml version="1.0"?>
    <configuration>
      <system.web>
        <compilation debug="true" targetFramework="4.0" />
      </system.web>
      <system.serviceModel>
        <bindings>
          <customBinding>
            <binding name="myWSBinding">
              <security defaultAlgorithmSuite="Basic128Rsa15"
                        allowSerializedSigningTokenOnReply="true"
                        enableUnsecuredResponse="true"
                        authenticationMode="MutualCertificate"
                        requireDerivedKeys="false"
                        securityHeaderLayout="Lax"
                        includeTimestamp="false"
                        messageProtectionOrder="SignBeforeEncrypt"
                        messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
                        requireSignatureConfirmation="false">
              </security>
              <StrippingChannel />
              <textMessageEncoding messageVersion="Soap11WSAddressingAugust2004"
                                   writeEncoding="utf-8" />
              <httpsTransport requireClientCertificate="false">
              </httpsTransport>
            </binding>
          </customBinding>
        </bindings>
        <behaviors>
          <endpointBehaviors>
            <behavior name="myWSBehavior">
    <!--
              <exClientBehavior />
    -->
              <!--
              <DispatchInspector />
    -->
              <clientCredentials>
                <clientCertificate findValue="ClientCertificate"
                                   storeLocation="LocalMachine"
                                   storeName="Root"
                                   x509FindType="FindBySubjectName" />
                <serviceCertificate>
                  <defaultCertificate findValue="ServerCertificate"
                                      storeLocation="LocalMachine"
                                      storeName="Root"
                                      x509FindType="FindBySubjectName" />
                </serviceCertificate>
              </clientCredentials>
            </behavior>
          </endpointBehaviors>
        </behaviors>
        <client>
          <endpoint address="https://server/service.asmx"
                    behaviorConfiguration="myWSBehavior"
                    binding="customBinding"
                    bindingConfiguration="myWSBinding"
                    contract="WSMainServices.MainServicesImplSoap"
                    name="MainServicesImplSoap">
            <identity>
              <dns value="ServerCertificate" />
            </identity>
          </endpoint>
        </client>
        <extensions>
          <bindingElementExtensions>
            <add name="StrippingChannel"
                 type="demoWSSecurity.StrippingChannelBindingElementExtensionElement, demoWSSecurity"/>
          </bindingElementExtensions>
          <behaviorExtensions>
            <add name="exClientBehavior"
                 type="demoWSSecurity.myWSClientBehaviorExtensionElement, demoWSSecurity" />
            <add name="DispatchInspector"
                 type="demoWSSecurity.myWSDispatchBehaviorExtensionElement, demoWSSecurity" />
          </behaviorExtensions>
        </extensions>
      </system.serviceModel>
    </configuration>

    Now, note that I've commented the exClientBehavior and DispatchInspector these are BehaviorExtensions that I tried, but didn't work. The only extension that

    I'm actually using is the BindingElementExtension StrippedMessage.

    This is my IRequestChannel implementation:

        public class StrippingRequestChannel : IRequestChannel, IDisposable
        {
           ...
            private static void DeleteHeader(System.ServiceModel.Channels.Message request, string encabezado)
            {
                int i = 0;

                foreach (MessageHeaderInfo mensaje in request.Headers)
                {
                    if (mensaje.Name == encabezado)
                    {
                        request.Headers.RemoveAt(i);

                        break;
                    }

                    i++;
                }
            }

            public Message Request(Message message, TimeSpan timeout)
            {
                DeleteHeader(message, "messageHeader");

                Message ret = null;

                ret = _innerChannel.Request(message, timeout);

                MessageBuffer buffer = ret.CreateBufferedCopy(int.MaxValue);

                MemoryStream stream = new MemoryStream(1024);

                buffer.WriteMessage(stream);

                stream.Position = 0;

                XmlDocument doc = new XmlDocument();

                doc.Load(stream);

                XPathNavigator n = doc.CreateNavigator();

                //if (n.MoveToFollowing("BinarySecurityToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"))
                //  n.DeleteSelf();

                //if (n.MoveToFollowing("Signature", "http://www.w3.org/2000/09/xmldsig#"))
                //  n.DeleteSelf();

                if (n.MoveToFollowing("Timestamp", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"))
                    n.DeleteSelf();

                n.MoveToRoot();

                XmlReader reader = n.ReadSubtree();

                Message strippedMessage = Message.CreateMessage(reader, int.MaxValue, ret.Version);

                return strippedMessage;
            }

      ...

    This is a quick fix for 2 probles that I got; delete a header called messageHeader and delete the Timestamp.When I create a proxy using WSDL (In Framework

    2.0) the firm of the getBankList method is:

    public getBankListResponseInformationType[] getBankList(getbankListInformationType getBankListInformation)


    But when I use svcutil (In Framework 4.0) the firm is:

    WSMainServices.getBankListResponse WSMainServices.MainServicesImplSoap.getBankList(WSMainServices.getBankListRequest request) ...

    And getBankListRequest is:

     
    public partial class getBankListRequest
    {
        public WSMainServices.MessageHeaderType messageHeader;

        public WSMainServices.getbankListInformationType getBankListInformation;

        public getBankListRequest() {
        }

        public getBankListRequest WSMainServices.MessageHeaderType messageHeader, WSMainServices.getbankListInformationType getBankListInformation) {
          this.messageHeader = messageHeader;

        this.getBankListInformation = getBankListInformation;
        }
    }

    So when I call the service, in my response it goes a message header called: messageHeader.

    This is my original Request:

    <s:Envelope xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
      <s:Header>
        <a:Action s:mustUnderstand="1">http://server/service/getBankList</a:Action>
        <h:messageHeader xmlns="http://www.uc-council.org/smp/schemas/eanucc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:h="http://www.uc-council.org/smp/schemas/eanucc" />
        <a:MessageID>urn:uuid:897713b5-fdfe-43a4-98fa-35035ca1552e</a:MessageID>
        <a:ReplyTo>
          <a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
        </a:ReplyTo>
        <VsDebuggerCausalityData xmlns="uIDPo8HoGuI6/rhIhFFPCBqXdB4AAAAAQ+YK2kBWlU

    +YZXWtWAlZij/7NDLM3zRAj5jCzE7+OagACQAAhttp://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo8HoGuI6/rhIhFFPCBqXdB4AAAAAQ+YK2kBWlU

    +YZXWtWAlZij/7NDLM3zRAj5jCzE7+OagACQAA</VsDebuggerCausalityData>
      </s:Header>
      <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <getBankList xmlns="http://www.uc-council.org/smp/schemas/eanucc">
          <getBankListInformation>
            <entityCode>123456</entityCode>
          </getBankListInformation>
        </getBankList>
      </s:Body>
    </s:Envelope>

    And when I call the service with that request, the service gives me the following exception:

    "SecurityVersion.WSSecurityJan2004 does not support header encryption. Header with name 'messageHeader' and namespace 'http://www.uc-

    council.org/smp/schemas/eanucc' is configured for encryption. Consider using SecurityVersion.WsSecurity11 and above or use transport security to encrypt the

    full message."

    That's why I have to delete the messageHeader header from the request.

    Then I have to delete the Timestamp, if I don't I got the exception:

    "The security header element 'Timestamp' with the 'Timestamp-e17f63d4-c87a-42f1-81e3-0dfb9b623dc1' id must be signed."

    So I delete it... now I'm getting the exception:

    "The 'messageHeader', 'http://www.uc-council.org/smp/schemas/eanucc' required message part  was not encrypted."

    If I deleted from the response (I shouldn't do it, because it gives me info by a ref parameter)...

    The 'Action', required message part  was not encrypted.

    ... All the headers the same thing..

    And that's what's making me crazy... WS-Security 1.0 doesn't use message header encryption... I've tried to delete all the headers from the response... even

    the Security... and then keeps telling me that the body should be encrypted...

    Where can I tell ... hey... don't encrypt anything... I'm using:

    WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10

    What I'm missing?

    Thanks a lot for any help you could give me!!

    Andrés Giraldo

    Thursday, January 26, 2012 7:03 PM