Security processor was unable to find a security header in the message. - wcf

In my many trials to debug this
Exception: `System.ServiceModel.Security.MessageSecurityException: Security processor was unable to find a security header in the message.
This might be because the message is an unsecured fault or because there is a
binding mismatch between the communicating parties. This can occur if the service is configured for security and the client is not using security`
How Do I debug a fault exception
I am not sure if this is why my response says 'Rejected by policy from client'
This is just a guess if it could be because of the additional junk which in soap header .
My code generated a soap header which looks like this
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<a:Action s:mustUnderstand="1" u:Id="_3"/>
<a:MessageID u:Id="_4">urn:uuid:9659b138-7fc0-4bb6-8c0a-bae00336ba78</a:MessageID>
<a:ReplyTo u:Id="_5">
<a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
</a:ReplyTo>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">
uIDPo/RnkzjA3fBPjgXUnYt8J3IAAAAAoMwUVXqfw0yigCfFtptf4RNq4s3l6eJLuuLNNdxRoH4ACQAA
</VsDebuggerCausalityData>
<a:To s:mustUnderstand="1" u:Id="_6">https://service100.emedny.org:9047/MHService</a:To>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:BinarySecurityToken u:Id="uuid-8d1465b7-c0fd-4137-9361-d0a818286435-53" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">
<!--Removed-->
</o:BinarySecurityToken>
<o:BinarySecurityToken u:Id="uuid-8d1465b7-c0fd-4137-9361-d0a818286435-52" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">
<!--Removed-->
</o:BinarySecurityToken>
</o:Security>
</s:Header>
...
</s:Envelope>
This is the sample soap request for vendor
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:mhs="http://org/emedny/mhs/" xmlns:urn="urn:hl7-org:v3">
<soapenv:Header>
<wsse:Security soap:mustUnderstand="1" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<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-e00c8062-83d2-4f04-88fc-996218e7bb3d">MIICeDCC....(eMedNY signed user MLS cert).......</wsse:BinarySecurityToken>
<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-c0cc2cd4-cb77-4fa5-abfa-bd485afd1685">MIIDFj.....( eMedNY MLS web-service end-point public cert)........</wsse:BinarySecurityToken>
This is the additional stuff my client code generates
<a:Action s:mustUnderstand="1" u:Id="_3"/>
<a:MessageID u:Id="_4">urn:uuid:9659b138-7fc0-4bb6-8c0a-bae00336ba78</a:MessageID>
<a:ReplyTo u:Id="_5">
<a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
</a:ReplyTo>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">
uIDPo/RnkzjA3fBPjgXUnYt8J3IAAAAAoMwUVXqfw0yigCfFtptf4RNq4s3l6eJLuuLNNdxRoH4ACQAA
</VsDebuggerCausalityData>
<a:To s:mustUnderstand="1" u:Id="_6">https://service100.emedny.org:9047/MHService</a:To>
How would I remove this?
Internet recommends using Imessageinspector and custombehviour
public class CustomMessageInspector : IClientMessageInspector
{
#region IClientMessageInspector Members
public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
}
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
{
request.Headers.RemoveAll("Action", "http://schemas.xmlsoap.org/ws/2004/08/addressing");
request.Headers.RemoveAll("MessageID", "http://schemas.xmlsoap.org/ws/2004/08/addressing");
request.Headers.RemoveAll("ReplyTo", "http://schemas.xmlsoap.org/ws/2004/08/addressing");
request.Headers.RemoveAll("To", "http://schemas.xmlsoap.org/ws/2004/08/addressing");
return null;
}
#endregion
}
public class CustomBehavior : IEndpointBehavior
{
<--removed some more classes-->
public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint, System.ServiceModel.Dispatcher.ClientRuntime behavior)
{
//Add the inspector
behavior.MessageInspectors.Add(new CustomMessageInspector());
}
}
then finally in the call to the proxyclient
MHSClient proxy = new MHSClient(GetCustomBinding(),
new EndpointAddress(new Uri("https://service100.emedny.org:9047/MHService"),
EndpointIdentity.CreateDnsIdentity("DPMedsHistory"));
proxy.Endpoint.EndpointBehaviors.Add(new CustomBehavior());
private static Custombinding GetCustomBinding()
{
var b = new CustomBinding();
var sec = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10);
sec.EndpointSupportingTokenParameters.Signed.Add(new X509SecurityTokenParameters());
sec.EndpointSupportingTokenParameters.Signed.Add(new UserNameSecurityTokenParameters());
sec.MessageSecurityVersion =
MessageSecurityVersion.
WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
sec.IncludeTimestamp = false;
sec.MessageProtectionOrder = System.ServiceModel.Security.MessageProtectionOrder.EncryptBeforeSign;
TextMessageEncodingBindingElement textEncBE = new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8);
HttpsTransportBindingElement httpsBE = new HttpsTransportBindingElement();
CustomBinding myBinding = new CustomBinding();
myBinding.Elements.Add(sec);
myBinding.Elements.Add(textEncBE);
myBinding.Elements.Add(httpsBE);
return myBinding;
}
THis doesn't work or rather gives me an error:
No signature message parts were specified for messages with the '' action.

Related

Missing security headers in FaultException

I'm using a custom binding in my service and client which basically looks like this:
public class UserNameWsTrustBinding : Binding
{
public override BindingElementCollection CreateBindingElements()
{
var coll = new BindingElementCollection();
coll.Add(CreateSecurityBindingElement());
coll.Add(new TextMessageEncodingBindingElement());
coll.Add(new HttpsTransportBindingElement());
return coll;
}
private SecurityBindingElement CreateSecurityBindingElement()
{
var elem = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
elem.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
return elem;
}
}
This binding works prety well. Except for FaultExceptions which I throw e.g. when validating the user's credentials.
I throw non-generic FaultExceptions like this; nothing special I think:
throw new FaultException(new FaultReason("Blah blah"), new FaultCode("Code42"));
WCF then takes care of putting these faults into a SOAP envelope. The problem is, that there don't get security headers (namely a WS-Security timestamp) baked in:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://www.w3.org/2005/08/addressing/soap/fault</a:Action>
<a:RelatesTo>urn:uuid:ff1f54d7-53a0-4650-b967-03a75def5fa4</a:RelatesTo>
</s:Header>
<s:Body>
<s:Fault>
<s:Code>
<s:Value>s:Sender</s:Value>
<s:Subcode><s:Value>Code42</s:Value></s:Subcode>
</s:Code>
<s:Reason><s:Text>Blah blah</s:Text></s:Reason>
</s:Fault>
</s:Body>
</s:Envelope>
When the client application receives this response it complains about it with the following error message:
System.ServiceModel.Security.MessageSecurityException: An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail.
This is not surprising, since there is no security header included. I can then get the FaultException from the MessageSecurity's InnerException. It works, but it doesn't feel good.
What is really surprising, however, is that unhandled exceptions that are not caught in my server code get wrapped in a FaultException automatically. And these FaultExceptions have a security header!
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<a:Action s:mustUnderstand="1">http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher/fault</a:Action>
<a:RelatesTo>urn:uuid:0baffa8b-07ee-4feb-bc44-7e2c7ae85c22</a:RelatesTo>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2022-07-11T13:41:22.007Z</u:Created>
<u:Expires>2022-07-11T13:46:22.007Z</u:Expires>
</u:Timestamp>
</o:Security>
</s:Header>
<s:Body>
<s:Fault>
<s:Code>
<s:Value>s:Receiver</s:Value>
<s:Subcode><s:Value xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</s:Value></s:Subcode>
</s:Code>
<s:Reason><s:Text>The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the %lt;serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework SDK documentation and inspect the server trace logs.</s:Text></s:Reason>
</s:Fault>
</s:Body>
</s:Envelope>
So, long story short: What am I doing wrong? Or in other words: What do I have to do to make my self-thrown FaultExceptions include a timestamp as well?

WCF Soap Service Deserialization failed (unrecognized element was encountered)

I build a WCF selfhosted WS (basichttp-binding) with 2 methods. Then created a WSDL and delivered it to a customer. Now they are sending SOAP-requests to the service but one of my methods (PostSendeplatz) fails everytime with a null parameter. In the trace I see the following:
<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Verbose">
<TraceIdentifier>http://msdn.microsoft.com/de-DE/library/System.Runtime.Serialization..aspx</TraceIdentifier>
<Description>An unrecognized element was encountered in the XML during deserialization which was ignored.</Description>
<AppDomain>RabbitServerTopSelf.vshost.exe</AppDomain>
<ExtendedData xmlns="http://schemas.microsoft.com/2006/08/ServiceModel/StringTraceRecord">
<Element>http://plantri.de:sendeplatz</Element>
</ExtendedData>
</TraceRecord>
I checked my namespaces in DataContracts, ServiceContract and ServiceImplementation:
[ServiceContract(Namespace = "http://plantri.de")]
public interface IRabbitImportService {
[OperationContract]
bool PostSendung(Sendung sendung, out string errorMsg);
[OperationContract]
bool PostSendeplatz(Sendeplatz sendePlatz, out string errorMsg);
}
...
[DataContract(Namespace = "http://plantri.de")]
public class Sendeplatz : RabbitIdBase { ...
...
[DataContract(Namespace = "http://plantri.de")]
public class Sendung : RabbitIdBase { ...
...
[ServiceBehavior(Namespace="http://plantri.de")]
public class RabbitImportService : Log4NetLogWriter, IRabbitImportService {
...
public bool PostSendung(Sendung sendung, out string errorMsg) {
... do something and return success
}
public bool PostSendeplatz(Sendeplatz sendePlatz, out string errorMsg) {
errorMsg = String.Empty;
if (sendePlatz == null) {
Error("no Sendeplatz send!");
return false;
}
... never came until this point!!!!
}
Here is a part of the soap-envelope which isn't deserialized (from the trace):
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<s:Header xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://192.168.40.64:8800/RabbitImportService</To>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://plantri.de/IRabbitImportService/PostSendeplatz</Action>
</s:Header>
<soapenv:Body>
<PostSendeplatz xmlns="http://plantri.de">
<sendeplatz>
<Id>1258878</Id>
...
But the working envelope looks quite the same:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<s:Header xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://192.168.40.64:8800/RabbitImportService</To>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://plantri.de/IRabbitImportService/PostSendung</Action>
</s:Header>
<soapenv:Body>
<PostSendung xmlns="http://plantri.de">
<sendung>
<Id>564589</Id>
...
I don't have a chance to change the client proxy which was writen by a customer (JAVA).
Did anyone have an idea to solve the problem?
But the working envelope looks quite the same: How?
<PostSendeplatz xmlns="http://plantri.de">
<sendeplatz>
<PostSendung xmlns="http://plantri.de">
<sendung>
I see these tag names differs.

WCF Client for Axis2/Rampart Webservice using WS security without client certificate

I´m just facing some problems setting up a WCF(.NET 4.0) webservice to call an Axis2 Rampart webservice.
I´m new to WCF and i didn´t find a tutorial wich completly fits this special scenario.
Here are the facts:
The webservice i have to call is an Axis2 Ramart service.
The Client i need to build uses WCF/.NET 4.0.
The Webservice uses SOAP 1.1 and WS-Security (Messagesecurity).
WS-Securtity should work like this:
The server provides a certificate with the public key.
The client generates a secret symmetric key.
The client encrypts this secret key with the servers public key.
This encrypted key is written into the Soap-header.
The client encrypts the body of the Soap request with the secret key.
(In fact the dodumentation I got from the webservice provider says that the body is encrypted with the servers public key, but in the sample request they provide, the encryption method is stated as aes128-cbc wich is a symmetric key AFAIK)
So this is what i have to do.
What i have done so far was to try some custom bindings from several tutorials.
But all samples I found uses server AND CLIENT-certificates and I didn´t managed to adjust these bindings in a way that works for me.
So here is a sample-request that shows how the request should look like:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
<xenc:EncryptedKey Id="EncKeyId-Cl6B57CC684EEpm8E6E61WBp3421878712">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1">D99lKi5jizWOxThG6yZXw6llwq4FdM=</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>Ab5i63RFNPNXcoEn6PqflaoPjsUI3E5EZh668621xkMcEDz9Jcm204A5Ecn8WQamxKX7UYEG8gPwn66X+pOj0DiWD4ShKVJIOD5gCliobcGgjVB1Uihj8Xk5MGesi8atuy9RFA=</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedKey>
<wsc:DerivedKeyToken xmlns:wsc="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="derivedKeyId-1">
<wsse:SecurityTokenReference>
<wsse:Reference URI="#EncKeyId-Cl6B57CC684EEpm8E6E61WBp3421878712"
ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey" />
</wsse:SecurityTokenReference>
<wsc:Offset>0</wsc:Offset>
<wsc:Length>16</wsc:Length>
<wsc:Nonce>wQ9oyLHKjKRx6Dlm04RaL5Q==</wsc:Nonce>
</wsc:DerivedKeyToken>
<xenc:ReferenceList>
<xenc:DataReference URI="#EncDataId-2" />
</xenc:ReferenceList>
</wsse:Security>
</soapenv:Header>
<soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Id-15079889">
<xenc:EncryptedData Id="EncDataId-2" Type="http://www.w3.org/2001/04/xmlenc#Content">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" />
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:Reference URI="#derivedKeyId-1" />
</wsse:SecurityTokenReference>
</ds:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>
+Tx9+XL7QqFVZKCr5wEhyOBENlCfHm0y1y5yWwnIk2kHNoO3IFFJj2rSQdt7HiqfcU6XxAVn3eVJKmmuN+rPYISoJstl8EnStaEIqSTuUyTUrgchx5Zxor47TOknXXjo3dYhTKHqvsx8SX70GG3M+bJS/Q1CWDlWzidKWxORo8D02iVcQdu00dnw7SHWYwyzzhduQbsozyzcAER5cYnQuuUPOcBusivq/L0xDOVTFaGr9/vvPGo+yk2bN0nBLeikk0uSJr7Z/IqGL+Dqg5BA0f+8X8sxFQpRQmtSoXtvhs2bGy8v1MPkCYKPmajSR/XwMaQB2zxR6vKsGA7ODH9+ocqO+rbPOYWpRz+czogOUo5s+OYIwX9u+99NmC5zuSjvK5bwJzWWrJ0h31OM0KeTkc7rxTIm8QMR5ytBNnCtU9QXQeAMbBdwGok330rq5ZH9bN4TdBg9Qhzs8CGGpjMYZaQ9ApTt6vkGK0i9gtdXdvY1fVZpsPcU67MYvkXJARQMpwj9Z3ZDVscdiPIxvfHyBkT8Ta21mDlYRidxanr87CrLB6HyiEyhD1XKwpTZ7OpNja6UOzfGNOJx07SbgGF+ozDBaC7zs691L4iawDioXagUZSkQ9UgwaqycSh3YYa5+RYuPka1Z0z2cmdAaFnEtoZAaSftGj8k=
</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</soapenv:Body>
</soapenv:Envelope>
Perhaps someone could tell me how I can accomplish this, or where I can find some tutorials.
Thank you in advance.
This is the Resposne I get after I´ve implementet the Custom Binding and the Messsage-Encoder:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
<wsc:DerivedKeyToken xmlns:wsc="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="derivedKeyId-159">
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKeySHA1">Aef7igYIlyWYa9XrbSYSt9Lh5Q4=</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
<wsc:Offset>0</wsc:Offset>
<wsc:Length>16</wsc:Length>
<wsc:Nonce>Ub30ogcNT6p7ZkH+qXFclw==</wsc:Nonce>
</wsc:DerivedKeyToken>
<wsc:DerivedKeyToken xmlns:wsc="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="derivedKeyId-159">
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKeySHA1">">Aef7igYIlyWYa9XrbSYSt9Lh5Q4=</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
<wsc:Offset>0</wsc:Offset>
<wsc:Length>16</wsc:Length>
<wsc:Nonce>Ub30ogcNT6p7ZkH+qXFclw==</wsc:Nonce>
</wsc:DerivedKeyToken>
<xenc:ReferenceList xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:DataReference URI="#EncDataId-160"/>
</xenc:ReferenceList>
</wsse:Security>
</soapenv:Header>
<soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Id-1046510178">
<xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="EncDataId-160" Type="http://www.w3.org/2001/04/xmlenc#Content">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:Reference URI="#derivedKeyId-159"/>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>zQUBHBX2nMTfL5gxXseNqqE5goAFSPQEd2D1RAsUZi+L64gqYfdQQIg//hWhw0Ed9gGFxLX8/ocq
svVX7oVTN4YkCF9LdLmY1y7/SmbDMyjKjzhxvQ5Bz2mu1EzWBtWRjAYGnMtLTJCCWEK0ZeqKGXDi
rqcHMwJYK4vGKeizAl/BMN2dLqp4gANSHB7kryGYiK4C2NncYwpbbws/It6Lm2RPuUenFW+2VCaC
OW8YdCMMfveEvO+18+BaApxS2ShckTbip9nbpDzVvGw4gFw/70xAupMkkUEGJPdBnb6ce9qC/jQm
MeBL4FSenEJbqR1qSU5xh6rD7m6Vqug5mEP7c2Tk/mPSFVlZ88TXV2S31NB+3PDAXxyZss9aftBl
L+q+m8oP/hqse9Oju8MaztP/gBQDSKuTBLWgMPvwluEZmnPnpItZX9CFOVGDaaWlnoN1Lgc6iKk/
8xDC95t87++NesK6Zqa+J15qGm4MozFBe5pS75wARrGA34USnHytNNJGyidx15wQgNrT9gxTlypQ
BU3830rWiWAsrFwzSQBC20TcNb0ofscNJqVhwmRnMHz75Gbn70jyGTM0W27PFYfq/xfJ3MCe/pov
Dqn647j2Ixvj/Rik02HJdUUm/cdmRxawWQVUvmxPbPNNOjCoccwOWxf623zXpD3DdV8U/5+jDite
eQnrpaU4griXc7jq85OIoghf++cShAK+tx5t8BjLaD1rBF3ni5Eqt2xbMoZ6cfzr314PxmffyjHM
rCzSMU4cw0BndzJrV2r0aKTEPxVRPIQur8ztEtIYCRWloceS4N2YKkdRm/W7TWBsIa+HOCpq9Rpr
bu0KLP54tBBTO5hzjIsjYn7JzfohYk5aDN/8ZsQqgsO0LhWu/9qj8j2fY+yC4W9i7m+/bLvuYSbO
Tm7B0vV5s79uG4Xi/ONM7O1NR/C1HSEddQnr0/zdDxJcJsxwAmyryILmLynaZyxeFYz5ueqQuNCZ
MTRvKdEfw2+Tt7l3lUSZ/WqPcAz2UFA7kdASk2esmQjVZjvvdLQfan7xHffU1Ga5nmafuXrCZR81
k+1OYs64oy14qFor0e3DXlyeUOPC67iEP92lBQl7hz4v9I0afSmEhmc3iR/XoYTgliP2QhkeEw11
gSGa9u6oLfQfGZVsDV6meL51kkM+FRKq8Y2QjJjSyVFUzQXmg0lAySjlTjVeYZbRCSleCSqk+tIJ
XIcsdkY9PSVxdWOiqXQcQlrae1Wj34Xf+h6NpNuIt/TSKxd896b0ACzz8ouHUvI/Wyk5Rz/Rmvzi
g/cGK9YnX8VGV2hpUzsVZLByUoWvMH+hv9ep1syQiA5EiIu+paTS92CW1i2x39pnKeMrYhI6Ug==</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</soapenv:Body>
</soapenv:Envelope>
And This is the ReadMessage-Function of My MessageEncoder (I know it´s not the best way to parse Xml). It removes one of the two derived keys:
public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType)
{
var msg = innerEncoder.ReadMessage(buffer, bufferManager, contentType);
var xml = msg.ToString();
var msgbuffer = msg.CreateBufferedCopy( int.MaxValue );
msg = msgbuffer.CreateMessage();
MemoryStream stream = new MemoryStream();
XmlDictionaryWriter xmlWriter = XmlDictionaryWriter.CreateBinaryWriter(stream);
msg.WriteMessage(xmlWriter);
xmlWriter.Flush();
stream.Position = 0;
XmlDictionaryReader xmlReader = XmlDictionaryReader.CreateBinaryReader(stream, XmlDictionaryReaderQuotas.Max);
XmlDocument doc = new XmlDocument();
doc.Load(xmlReader);
XmlNode security = null;
XmlNode derivdeKey = null;
foreach (XmlNode xnode in doc.DocumentElement.FirstChild.ChildNodes)
{
if (xnode.LocalName == "Security")
foreach (XmlNode node in xnode.ChildNodes)
{
security = node;
if(node.LocalName == "DerivedKeyToken")
{
}
if(derivdeKey != null)
{
XmlNode pnode = node.ParentNode;
pnode.RemoveChild( node );
}
else
{
derivdeKey = node;
}
}
}
Stream memStream = new MemoryStream();
xmlWriter = XmlDictionaryWriter.CreateBinaryWriter( memStream );
doc.WriteTo(xmlWriter);
xmlWriter.Flush();
memStream.Position = 0;
xmlReader = XmlDictionaryReader.CreateBinaryReader(memStream, XmlDictionaryReaderQuotas.Max);
Message newMessage = Message.CreateMessage(xmlReader, 10240, msg.Version);
xml = newMessage.ToString();
return newMessage;
}
I`m wondering about how the Message is shown as string (newMessage.ToString()) because the body is shon was ...stream....
The Problem is that I get the followingError-message:
System.ServiceModel.Security.MessageSecurityException : The 'Body', 'http://schemas.xmlsoap.org/soap/envelope/' required message part was not signed.
So I stripped of the Security node as descriped here http://webservices20.blogspot.de/2012/04/when-enableunsecuredrespose-requires.html.
This is the stripped resonse:
<?xml version="1.0" encoding="utf-16"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body wsu:Id="Id-1532543044" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><xenc:EncryptedData Id="EncDataId-586" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"></xenc:EncryptionMethod><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><wsse:Reference URI="#derivedKeyId-585"></wsse:Reference></wsse:SecurityTokenReference>
</ds:KeyInfo><xenc:CipherData><xenc:CipherValue>APZ9aATpcMu5qU6PdoKeTLjAblJP/uLZAzX8imgSSfvaZGGeI8prg9JNTEOjZ1SAeuWxod/ZV4pb
3OeY3b1IWxxhG5WWGxu51WAAehGBmiyFYOzJwbpR5cOHUc7aRBm7hkeqr/1RlcYDlAk4Y+G1URgv
0K2nzqfDR3m7ydZSVoa3aSWWzmhjMTnJnPyQ060fDXiU7/k0tI12danfv+tUcBAlvfssTTEB33bH
RXTjobJDuW3lEbbQBN+KD9SUu02GvFF4Vs31pSf1YxHIzMuf3Q2njz58oY0kmDRvR6+n9IIUQVgK
5+iJOx9E5pY7xzmEf5LpbiTt2RSuxmt2+nkin+wxF94hkgW/N6TwmbbjybN2TY3IyZ2PgdzobCj9
sG9UAwAE1peDvIpiXhgXyojU7eRnAfJKE4HrxEjs9GKdgA4SG3rsM7t/JAeiThqe4GZCvrKwnTHS
OZSz8wplTEV7VfALj5TvwK8DqOP4Qsk1F6pml/IQg0YSUJGQmuxZzTiM3ABRzf21/BUj9j3mlo7R
/QFhNnEAhHTLoJIW1fhKYrhT7vk6rMLlZtP7iyE63MEp4cghvSk9OZDauUBoUAkKwv9N2TSOBe3W
N0fVIpLg+gNmu8s1Myzl9MEDpqQFvJbG2+hTjREo9cyvfJdKLjZVpWVoaaghiZrOFwUWJsIGCyuy
aW+eF1wFP6WgXixmvX/mdkEqCyU29+DAlIb5yIABgIxNk4MSJP/9+cSZ7L6EOVJc9khsMgw1aGe9
k3QbIeM7WLXcHNnWFE+PuqORg7OvvG+jqFGyfGlGaE85lbD2+0ONTmxU3MwNhg9ngZLheiIzxxty
3R2KXDMkDEQpWJ7cIi2QSvwu0XZ/Ku5hwW8fXbUgHTClpAQbwu3HqeeHv2BkhrUbPbx3pRpu6B4L
tyGO4vfp/vlnPyT0xS5O99KX6iKpDDS3zqC9j0cheJIqIvixNvrLd/KrpQJ8nc7+B/29h444y/3I
jooRtDmtNuG2T3b4QB2oec7FS+ufXUJIEgPWtE6iPMZxMqiL1z64eL0sg2xO4QXWwoGzMCZHP89y
ibhjhsKDTffz/s4cgRgzRWAQSNlLpuvzDeHjbNUnXIz3C1NnQOBV0LF5KpCuyYeIfQDbJQpyTre1
q5KMTGHq4ksG2zSpgNNouS279WmlGOmuawLW28VxRBlW92K//l16yJglEcKbqlRuxzM0gcw1BG/O
9sp25te+Ad68Vo2dyELZYstIRhSnV2j2J6UyZd1WC1rBWHiu3gDvKgeCNtgUbeHKfm0RVo9ZBVbi
vHQWAL57hOBERoXK5MkhwqlsYZzOHzkoVyxok+UspcmVy1MQccOcB6y5xbuqt6zR+iFuKyZVGQ==</xenc:CipherValue></xenc:CipherData></xenc:EncryptedData></soapenv:Body></soapenv:Envelope>
Now the Service finishes without errors, but the result-object is null.
-> example:
result = testserviceproxy.testservicefunction();
result is null;
This binding is the closest you could get with ootb wcf:
<customBinding>
<binding name="NewBinding0">
<textMessageEncoding messageVersion="Soap11" />
<security defaultAlgorithmSuite="Basic128Rsa15" authenticationMode="AnonymousForCertificate"
includeTimestamp="false" messageProtectionOrder="EncryptBeforeSign">
<secureConversationBootstrap />
</security>
<httpTransport />
</binding>
</customBinding>
It produces a very similar XML with one different: It also adds a digital signature. There is no way to directly tell WCF not to add a signature. Most chances are this will not be a problem for you to send the message as is (with signature). If this is a problem you could implement a WCF custom message encoder to manually remove the signature element (and also the one out of two derived keys which is used specifically for signature).

Wcf Backward compatibility issue - missing namespace on method parameter

we are hosted our WCF web service in windows service. We are using basicHttpBinding. We need preserve backward compatibility with Soap 1.1 Web service. Our problem is missing namespace on element EPTalkMessage in web method parameter. I searched a lot but I didn't find some way to add namespace to this element.
Soap from old web service is:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://aaa.sk/EPTalk/IssueDocument</Action>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<IssueDocument xmlns="http://aaa.sk/EPTalk">
<EPTalkMessage xmlns="http://aaa.sk/EPTalk/ToSignInput" />
</IssueDocument>
</s:Body>
</s:Envelope>
New generated soap is:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://aaa.sk/EPTalk/IssueDocument</Action>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<IssueDocument xmlns="http://aaa.sk/EPTalk">
<EPTalkMessage />
</IssueDocument >
</s:Body>
</s:Envelope>
Service signature is as follows:
[ServiceContract (Namespace = "http://aaa.sk/EPTalk")]
[XmlSerializerFormat(Use = OperationFormatUse.Literal, Style = OperationFormatStyle.Document)]
public interface IRegistryInputWebService
{
[OperationContract(Action = "http://aaa.sk/EPTalk/IssueDocument")]
RegistryServiceResult IssueDocument([MessageParameter(Name = "EPTalkMessage")]
UpvsPortalEmulator.ToSignInput.EPTalkMessage message);
}
Binding:
BasicHttpBinding
{
MaxReceivedMessageSize = 1024 * 1024 * 10,
MaxBufferSize = 1024 * 1024 * 10,
ReaderQuotas =
{
MaxArrayLength = 1024 * 1024 * 10,
MaxStringContentLength = 1024 * 1024 * 10
},
MessageEncoding = WSMessageEncoding.Text,
Security = new BasicHttpSecurity
{
Mode = BasicHttpSecurityMode.None
}
};
Edited: EPTalkMessage definition added.
[XmlType, XmlRoot (ElementName = "EPTalkMessage", Namespace = Declarations.SchemaVersion, IsNullable = false), Serializable]
public class EPTalkMessage
{
}
Thanks a lot for your help
After searching for a while, I resolved this issue with MessageContracts.

Invoke WCF service dynamically during runtime

I am trying to invoke WCF service dynamically. I am able connect to the service and invoke methods that do not require any parameters.
ChannelFactory<IRequestChannel> factory = new ChannelFactory<IRequestChannel>(this.ServiceBinding, this.EndPoint.Address);
IRequestChannel channel = factory.CreateChannel();
However, I am unable to invoke Operation Contracts that require composite Entity as a parameter.
The following code is used to instantiate the request Message:
Message requestMessage = Message.CreateMessage(this.ServiceBinding.MessageVersion, contractNameSpace, new SimpleMessageBody(value));
The value used in SimpleMessageBody class is serialized value of the entity using DataContractSerializer.
<Person xmlns="http://schemas.datacontract.org/2004/07/WcfService.Test.Service" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Name>John Smith</Name></Person>
Operation Contract
public string GetData(Person value)
{
using (MemoryStream ms = new MemoryStream())
{
value = new Person { Name = "John Smith" };
DataContractSerializer ser = new DataContractSerializer(typeof(Person));
ser.WriteObject(ms, value);
var result = UnicodeEncoding.UTF8.GetString(ms.ToArray());
}
return string.Format("You entered: {0}", value.Name);
}
Entity
[DataContract]
public class Person
{
[DataMember]
public string Name { get; set; }
}
The following SOAP message is generated from the above createmessage code:
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<a:Action s:mustUnderstand="1">http://tempuri.org/IService1/GetData</a:Action>
<a:MessageID>urn:uuid:cf78d5b7-333b-40eb-a71c-d81cb9c37b5d</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="1">http://localhost:52724/Service1.svc</a:To>
</s:Header>
<s:Body><Person xmlns="http://schemas.datacontract.org/2004/07/WcfService.Test.Service" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Name>John Smith</Name></Person></s:Body>
</s:Envelope>
However, in order for the Person entity to be populated and the correct operation contract to be executed the SOAP has to be as follows:
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<a:Action s:mustUnderstand="1">http://tempuri.org/IService1/GetData</a:Action>
<a:MessageID>urn:uuid:d49bd525-0f30-46fe-94fb-0248c2cb1ea2</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
</s:Header>
<s:Body>
<GetData xmlns="http://tempuri.org/">
<value xmlns:d4p1="http://schemas.datacontract.org/2004/07/WcfService.Test.Service" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<d4p1:Name>John Smith</d4p1:Name>
</value>
</GetData>
</s:Body>
</s:Envelope>
Please NOTE the message body.
Thanks
I don't know why are you doing it this hard way but if you want to call the method expecting SOAP request you shown you must first provide message contract to your client:
[MessageContract(WrapperName="GetName")]
public class MessageContract
{
[MessageBodyMember(Name="value")]
public Person Person { get; set; }
}
And you will also need similar contract for response.
Default serialization uses wrappers inferred from operation contract names but because you are not providing service contract your serializer doesn't know about existing wrappers because of that you have to provide this additional knowledge manually or redefine your service so that it doesn't expect wrappers elements (it is also done with message contracts and setting their IsWrapped properties to false).