I am at the beginner stage in SOAP services and I need to obtain a SAML assertion from an external source, and then pass it directly into the wsse:Security header of an outgoing WCF/SOAP message.
I am creating a client for a server API I can't change. The reply of the server to my request is:
<env:Body>
<env:Fault>
<faultcode>env:Client</faultcode>
<faultstring>Internal Error (from client)</faultstring>
</env:Fault>
</env:Body>
I'm not sure what is the cause of the problem but I don't have a XSD to verify the structure of the XML. My client currently produces a XML file with the following structure :
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<saml:Assertion></saml:Assertion>
</Security>
</s:Header>
<s:Body></s:Body>
</s:Envelope>
This is an example of XML from who control the server API:
<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">
<saml:Assertion></saml:Assertion>
</Security>
</soapenv:Header>
<soapenv:Body></soapenv:Body>
</soapenv:Envelope>
I tried to follow this guide to solve my problem https://www.outsystems.com/forums/discussion/74369/how-to-change-add-prefix-to-soap-request/ or other suggestion in StackOverflow but it doesn't work, this is my code:
public void SendRequest(X509Certificate2 certificate, ReperimentoDichiarazionePrecompilataCAFPortClient client)
{
client.Endpoint.Binding = GetCustomBinding();
client.ClientCredentials.ClientCertificate.Certificate = certificate;
client.ClientCredentials.ServiceCertificate.DefaultCertificate = certificate;
client.Endpoint.Contract.ProtectionLevel = System.Net.Security.ProtectionLevel.Sign;
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(AcceptAllCertifications);
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
MessageHeader aMessageHeader = MessageHeader.CreateHeader("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", assertion);
OperationContext.Current.OutgoingMessageHeaders.Add(aMessageHeader);
rispostaDichiarazionePrecompilataCAF1 result = await client.InterrogazioneDichiarazionePrecompilataCAFAsync(richiesta);
}
private System.ServiceModel.Channels.Binding GetCustomBinding()
{
var transpor = new HttpsTransportBindingElement();
transpor.RequireClientCertificate = true;
var textMessageEncoding = new TextMessageEncodingBindingElement();
textMessageEncoding.MessageVersion = MessageVersion.Soap11;
var version = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10;
var security = SecurityBindingElement.CreateMutualCertificateBindingElement(version,true);
return new CustomBinding(security,textMessageEncoding, transpor);
}
I tried to intercept the request and changing with BeforeSendRequest of the class SimpleMessageInspector, but it doesn't work either