I am trying to connect to a SSL SOAP service host by C# using Service Reference. This is my request message:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <s:Header> <VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo/zwMmtdsVhFsAVDkQbiV/4AAAAA1zXtnc72UEm+4tlKzvCxsvN6OC2prvRIljIX4XzHKEYACQAA</VsDebuggerCausalityData> <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>2016-03-18T12:45:27.558Z</u:Created> <u:Expires>2016-03-18T12:50:27.558Z</u:Expires> </u:Timestamp> <o:UsernameToken u:Id="uuid-2c7986ba-eee5-4411-90a9-a02b625c55ff-1"> <o:Username>MyUserName</o:Username> <o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">MyPlainPassword</o:Password> </o:UsernameToken> </o:Security> </s:Header> <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <generateId xmlns="http://com.vedaadvantage/dp3/Enterprise/StandardTradeCreditCommercial/IndividualCommercialService"/> </s:Body> </s:Envelope>
This is the message that my service sends to the host. But the host returns as below:
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.
This is my config file:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <bindings> <customBinding> <binding name="myBinding"> <textMessageEncoding messageVersion="Soap11" /> <security authenticationMode="UserNameOverTransport" messageSecurityVersion="WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10" > </security> <httpsTransport /> </binding> </customBinding> </bindings> <client> <endpoint address="https://{URL}" binding="customBinding" bindingConfiguration="myBinding" contract="ServiceReference2.MyService" name="IndividualCommercialService" /> </client> </system.serviceModel> </configuration>
Although when I send the same XML via SOAPUI or other HTTP Post methods it works fine.
I also extract and attached the certificate and user/pass as below:
private static X509Certificate2 DownloadSslCertificate(string strDNSEntry) { X509Certificate2 cert = null; using (TcpClient client = new TcpClient()) { //ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3; client.Connect(strDNSEntry, 443); SslStream ssl = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null); try { ssl.AuthenticateAsClient(strDNSEntry); } catch (AuthenticationException e) { //log.Debug(e.Message); ssl.Close(); client.Close(); return cert; } catch (Exception e) { //log.Debug(e.Message); ssl.Close(); client.Close(); return cert; } cert = new X509Certificate2(ssl.RemoteCertificate); ssl.Close(); client.Close(); return cert; } } private static void Main(string[] args){ var proxy = new MyService(); var uri = proxy.Endpoint.Address.Uri; var cer = DownloadSslCertificate(uri.DnsSafeHost); EndpointIdentity identity = EndpointIdentity.CreateDnsIdentity(cer.Subject.Replace("CN=", "")); EndpointAddress address = new EndpointAddress(proxy.Endpoint.Address.Uri, identity); proxy.Endpoint.Address = address; proxy.ClientCredentials.UserName.UserName = "MyUserName"; proxy.ClientCredentials.UserName.Password = "MyPlainPassword"; proxy.ClientCredentials.ServiceCertificate.DefaultCertificate = cer; proxy.HellowWorld(); }
I am not sure whether the method that I am getting the certificate is correct or not and also why HTTP Post works but my Service Reference Call does not.
Thanks in advance for your help.
Cheers
1 Answers
Answers 1
Try to look inside WSDL (Service References) in order to see hidden files first select Show All Files in Solution explorer. You`ll se inside service reference Reference.svcmap -> Reference.cs, and inside of this file add ProtectionLevel = System.Net.Security.ProtectionLevel.Sign as shown below
[System.ServiceModel.ServiceContractAttribute(Namespace = "http://www.your.url/Service/", ConfigurationName = "Service.Service", ProtectionLevel = System.Net.Security.ProtectionLevel.Sign)]
that should help you. Usually it`s really bad idea to modify autogenerated proxy, but seems like that is the only option.
0 comments:
Post a Comment