WCF Client consuming a non-WCF service - MessageSecurityException
-
Tuesday, June 29, 2010 5:42 AM
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();
All Replies
-
Tuesday, June 29, 2010 11:55 AMI 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 12:14 PM
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 8:36 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. -
Saturday, July 03, 2010 5:58 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 ZhaoModerator Tuesday, July 06, 2010 10:04 AM
- Unmarked As Answer by NNarhinen Tuesday, July 06, 2010 7:20 PM
-
Wednesday, July 07, 2010 4:42 AMModerator
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 6:47 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 NNarhinen Wednesday, July 07, 2010 6:48 AM
-
Friday, November 05, 2010 12:36 PM
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?
-
Sunday, January 02, 2011 6:23 PM
Hi,
IIRC you need to specify AllowUnsecuredResponse=true in your custom binding.
Regards,
Niklas
-
Thursday, January 20, 2011 2:54 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
-
Friday, January 28, 2011 2:24 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
-
Thursday, February 17, 2011 12:03 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, January 26, 2012 7: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 thatI'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 Framework2.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

