Reputation: 24
.net core- Call a soap service with wss security header
In my .net core class library project I have added reference to a WCF sevrvice(using a wsdl file) and now I have reference class generated under Connected Services. I am able to call the WCF service with a BasicHttpBinding, but the issue is that the server also expect a security element along with the SOAP header
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<wsse:Security
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">
<ds:Signature Id="SIG-"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
</ds:SignedInfo>
<ds:SignatureValue>==gMg==</ds:SignatureValue>
<ds:KeyInfo Id="KI-">
</ds:KeyInfo>
</ds:Signature>
<wsu:Timestamp wsu:Id="TS-34A069E7A55FECD03D16098926271579">
</wsu:Timestamp>
</wsse:Security>
<wsa:Action>http://www.test.com/Namespace/test_action</wsa:Action>
<wsa:MessageID>uuid:XXX</wsa:MessageID>
</soapenv:Header>
</soapenv:Envelope>
So basically I want the SOAP message to have this kind of security tag attached to the header. Please see above sample SOAP.
Thanks in advance :-)
Upvotes: 1
Views: 3017
Reputation: 490
I was getting below error
Security requirements are not satisfied because the security header is not present in the incoming message
To those who are finding difficulty with Generated classes by service connection.
Here is what worked for me.
var binding = new BasicHttpBinding();
binding.MaxReceivedMessageSize = int.MaxValue;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
binding.Security.Mode = BasicHttpSecurityMode.TransportWithMessageCredential;
var url = new System.ServiceModel.EndpointAddress("https://example.com/Service.asmx");
var client = new SoapClient(binding, url);
client.ClientCredentials.UserName.UserName = "xxxxxx";
client.ClientCredentials.UserName.Password = "xxxxxx";
Upvotes: 0
Reputation: 24
So the problem was to add a security header to the SOAP request. I found, that with configuration in your bindings you can send security header as well. You may not need any extra code for it.
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="ClientBehavior">
<clientCredentials>
<clientCertificate findValue="<certificate thumbprint here >" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint"/>
<serviceCertificate>
<authentication revocationMode="NoCheck"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="BasicHttpBinding_IExampleService">
<security
defaultAlgorithmSuite="Default"
requireDerivedKeys="false"
messageProtectionOrder="SignBeforeEncrypt"
requireSignatureConfirmation="false"
securityHeaderLayout="Lax"
messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
includeTimestamp="true"
>
<localClientSettings detectReplays="true" />
<localServiceSettings detectReplays="true" />
</security>
<textMessageEncoding messageVersion="Soap11" />
<httpTransport />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://localhost:63454/ExampleService.svc"
binding="customBinding" bindingConfiguration="BasicHttpBinding_IExampleService"
contract="ServiceReference1.IExampleService" name="BasicHttpBinding_IExampleService" behaviorConfiguration="ClientBehavior" >
<identity>
<certificateReference findValue="<certificate thumbprint here >" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" />
</identity>
</endpoint>
</client>
</system.serviceModel>
Upvotes: 0
Reputation: 3974
You can do it by building my custom header:
public class SoapSecurityHeader : MessageHeader
{
......
}
We're then adding this to the SOAP header in the BeforeSendReply method, something like this:
public class MessageInspector : IClientMessageInspector
{
public void AfterReceiveReply(ref Message reply, object correlationState)
{
throw new NotImplementedException();
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
SoapSecurityHeader head = new SoapSecurityHeader();
request.Headers.Add(head);
}
}
Finally, you need to apply MessageInspector to the service. If you can't apply MessageInspector to the service, you can refer to this link.
Upvotes: 0