Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Распределённые приложения и сеть > Правильное подключение к WCF веб-сервису.


Автор: MFSham 24.10.2013, 17:57
Сразу скажу никогда до этого с wcf не работал.
Задача минимум:
- создать правильное soap сообщение и отправить на веб-сервис
- получить от них ответ (хоть какой, но показывающий что наше сообщение было обработано)

Что имеется:
RootCATest - мой самоподписанный сертификат
Код

            static void Main(string[] args) {
            Uri ohipUri = new Uri("https://ws.ebs.health.gov.on.ca:1441/EDTService/EDTService");
            EndpointAddress endpointAddress = new EndpointAddress(ohipUri, EndpointIdentity.CreateDnsIdentity("RootCATest"));
            Binding binding = GetBinding();


            var serviceClient = new EDTDelegateClient(binding, endpointAddress);
            serviceClient.Endpoint.Name = "EDTService";
            if (serviceClient.ClientCredentials != null)
            {
                serviceClient.ClientCredentials.ClientCertificate.Certificate = GetCertificateFromStore("Entrust.net Certification Authority (2048)");
                serviceClient.ClientCredentials.ServiceCertificate.DefaultCertificate = GetCertificateFromStore("Entrust.net Certification Authority (2048)");
                serviceClient.ClientCredentials.UserName.UserName = "xxxxx@gmail.com";
                serviceClient.ClientCredentials.UserName.Password = "xxxxx";
            }

            EDTDelegate edt = serviceClient;
            
            try
            {
                listRequest request = new listRequest(EBSHeader, null, IDPHeader, "", resourceStatus.SUBMITTED, "1");
                var response = edt.list(request);                
            }
            catch (Exception ex)
            {
                string s = ex.Message;
            }
}

        /// <summary>
        /// Get certificate
        /// </summary>
        private static X509Certificate2 GetCertificateFromStore(string certName)
        {
            // Get the certificate store for the current user.
            X509Store store = new X509Store(StoreLocation.CurrentUser);
            try
            {
                store.Open(OpenFlags.ReadOnly);
                // Place all certificates in an X509Certificate2Collection object.
                X509Certificate2Collection certCollection = store.Certificates;
                X509Certificate2Collection signingCert = certCollection.Find(X509FindType.FindBySubjectName, certName, true);                
                // Return the first certificate in the collection, has the right name and is current.
                return signingCert[0];
            }
            finally
            {
                store.Close();
            }
        }

        private static WSHttpBinding GetBinding()
        {
            WSHttpBinding binding = new WSHttpBinding();
            binding.Name = "ohipWsHttpBinding";
            binding.Namespace = "EdtDelegateService.EDTDelegate";
            // Аутентификация клиента контролируется посредством атрибута ClientCredentials. элемента <transport> для <wsHttpBinding>.
            // http://msdn.microsoft.com/ru-ru/library/ms731362.aspx            
            binding.Security.Mode = SecurityMode.TransportWithMessageCredential;
            binding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
            //binding.Security.Message.EstablishSecurityContext = false;                       

            return binding;
        }

        /// <summary>
        /// idp_header
        /// </summary>
        private static idp_header IDPHeader
        {
            get
            {
                idp_header idpHeader = new idp_header();
                idpHeader.ServiceUserMUID = Guid.NewGuid().ToString(); // incorrect value
                return idpHeader;
            }
        }

        /// <summary>
        /// MSA (Master Service Agreement)
        /// msa_header
        /// </summary>
        private static msa_header MSAHeader
        {
            get
            {
                msa_header msaHeader = new msa_header();
                msaHeader.ServiceUserMUID = Guid.NewGuid().ToString(); // incorrect value
                return msaHeader;
            }
        }

        /// <summary>
        /// EBS (Electronic Business Services)
        /// ebs_header
        /// </summary>
        private static ebs_header EBSHeader
        {
            get
            {
                ebs_header ebsHeader = new ebs_header();
                ebsHeader.AuditId = "1233"; // incorrect value
                ebsHeader.SoftwareConformanceKey = "123456789"; // incorrect value
                return ebsHeader;
            }
        }


SOAP Header сообщение которое по спецификации правильное:
Код

<soapenv:Header>
<ns2:EBS wsu:Id="id-1" xmlns:ns2="http://ebs.health.ontario.ca/" >
<SoftwareConformanceKey>444361ee-277f-7732-c684-7a9923jfgh1b</SoftwareConformanceKey>
<AuditId>35870880-3701-47b7-a34d-439ee754d211</AuditId>
</ns2:EBS>
<ns2:IDP wsu:Id="id-2" xmlns:ns2="http://idp.ebs.health.ontario.ca/" >
<ServiceUserMUID>4523894</ServiceUserMUID>
</ns2:IDP>
<wsse:Security SOAP-ENV:mustUnderstand="1">
<wsu:Timestamp wsu:Id="id-3">
<wsu:Created>2012-06-20T17:58:42.580Z</wsu:Created>
<wsu:Expires>2012-06-20T17:59:12.580Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken wsu:Id="id-4">
<wsse:Username>SUTESTDEVONE@YAHOO.CA</wsse:Username>
<wsse:Password Type="wsse:PasswordText">Cliffsammy12!</wsse:Password>
</wsse:UsernameToken>
<wsse:BinarySecurityToken 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/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
wsu:Id="X509-02F859690D5C74E20913402151228211">MIICMzCCAZygAwIBAgIET1e+dDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJDQTEQMA4GA1UECBMHT250YXJpbzENMAsGA1UEChMET0hJUDEVMBMGA1UECxMMUmVnaXN0cmF0aW9uMRcwFQYDVQQDEw4xNDIuMTQ1LjcwLjE3NzAeFw0xMjAzMDcyMDAwNTJaFw0xMzAzMDcyMDAwNTJaMF4xCzAJBgNVBAYTAkNBMRAwDgYDVQQIEwdPbnRhcmlvMQ0wCwYDVQQKEwRPSElQMRUwEwYDVQQLEwxSZWdpc3RyYXRpb24xFzAVBgNVBAMTDjE0Mi4xNDUuNzAuMTc3MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCs/JIP6CE5IkfTnD/c56K+QAYqETdLvW1xXJ6ipkVhjjC2ASKuuH4fvhbyxo2B4VugsL9r4E5jHEKoi+GDKOLlLZRfSy0cB8IcpXonAuGqMzhCoEQ1CdxNb9etMyvQGRKEBgniKKxTvpTyZdpYDi92up5E+FYL3jEejhp+1iDFJQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAHn8VZS169BJMa4E6SNLnY7u80zSh90mbrTUWjM1dEicv3jQMMsrWHfoCt+nRSqfNLUTLc8U0LqiB3jnnNJgJt1T7Sp8eUZPdH0gY3i83ZXA8HDFKMZF3qL8I8ncu8FPcZGYBNhYrGjXXsuqXimiTIjxgm06ErRa/51szOFFxWrB</wsse:BinarySecurityToken>
Electronic Business Services Sensitivity: Low
Final December 2012 Version 3.0 Page 34 of 37
<ds:Signature Id="SIG-6" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" >
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="SOAP-ENV ebs soap-sec soapenv sp tns wsdl wsp wsse wsu xs xsi"
xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<ds:Reference URI="#id-1">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces
PrefixList="SOAP-ENV ebs soap-sec soapenv sp tns wsdl wsp wsse wsu xs xsi" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>gpejbitTQxuMOhUirdbGNtHjsGhAArhAp3ByFuG9cHs=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#id-2">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces
PrefixList="SOAP-ENV ebs soap-sec soapenv sp tns wsdl wsp wsse wsu xs xsi" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>ZWKvgN+eB0NFmQHPGYN5RoSZzbuboqKLzLcV6PEOz3E=</ds:DigestValue>
</ds:Reference>
Electronic Business Services Sensitivity: Low
Final December 2012 Version 3.0 Page 35 of 37
<ds:Reference URI="#id-3">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces
PrefixList="SOAP-ENV ebs soap-sec soapenv sp tns wsdl wsp wsse xs xsi" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>1AvUG2EE6+bgpJBe1TB4teUkKD4lRsw69BozDFQMGGE=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#id-4">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces
PrefixList="SOAP-ENV ebs soap-sec soapenv sp tns wsdl wsp wsu xs xsi" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>Lw6C0//TpU0uuta+9pjDPfD0aOokdgbVOEM9eaWcGjo=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#id-5">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="SOAP-ENV ebs soap-sec sp tns wsdl wsp wsse wsu xs xsi"
xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"
/>
</ds:Transform>
Electronic Business Services Sensitivity: Low
Final December 2012 Version 3.0 Page 36 of 37
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>lGKOfXxmbsLds9+tD4eaCObTCdGNXDF/PY9LjDUPl9Y=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
Yn5iRnjs/T2+nNgW8pArIgqc445RwL2wYPHZaydVJk0oUXV5B4nzU4fgX/sQTcY0O5vuReP8th4QZoGG6tSnxuBfqiDd2rkRZDrdgotJT++WzhMLdt1J0Kah0aZVCWabQrxeGY2N3QDuMWr5PSlm1RWbkA3W5B4YLaD+S/j3QKc=
</ds:SignatureValue>
<ds:KeyInfo Id="KI-02F859690D5C74E20913402151228312">
<wsse:SecurityTokenReference wsu:Id="STR-02F859690D5C74E20913402151228413">
<wsse:Reference URI="#X509-02F859690D5C74E20913402151228211" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</soapenv:Header>


Мой код возвращает ошибку 
Код

An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail.

Из tracelog
Код

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


Что отлавливает fiddler
Код

<s:Header>
<a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT</a:Action>
<a:MessageID>urn:uuid:244ef530-f6fe-4a5c-baa2-aea39782d82d</a:MessageID>
<a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo><a:To s:mustUnderstand="1">https://ws.ebs.health.gov.on.ca:1441/EDTService/EDTService</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">
<u:Timestamp u:Id="_0"><u:Created>2013-10-24T14:36:30.772Z</u:Created>
<u:Expires>2013-10-24T14:41:30.772Z</u:Expires></u:Timestamp>
<o:UsernameToken u:Id="uuid-04cccfce-91e9-49fc-9a20-e1f6b3ffe409-1">
<o:Username>xxxxxxx.com</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">xxxxxx</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>


Из этого soap сообщения видно что мое сообщение, мягко говоря, далеко от нужного.
В частности отсутствуют заголовки EBS и IDP, присутствует секция Security но в ней только инфа про Username/pass.

Если я поменяю тип биндинга на Transport, то получу следующее сообщение:
Код

<s:Header>
<a:Action s:mustUnderstand="1">http://edt.health.ontario.ca/EDTDelegate/listRequest</a:Action>
<h:EBS xmlns:h="http://ebs.health.ontario.ca/" xmlns="http://ebs.health.ontario.ca/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SoftwareConformanceKey xmlns="">123456789</SoftwareConformanceKey>
<AuditId xmlns="">1233</AuditId>
</h:EBS>
<h:IDP xmlns:h="http://idp.ebs.health.ontario.ca/" xmlns="http://idp.ebs.health.ontario.ca/">
<ServiceUserMUID xmlns="">648c02ae-5ecf-4ee5-ab75-d90de2538c77</ServiceUserMUID>
</h:IDP><a:MessageID>urn:uuid:8050f731-425f-4fee-819e-81925605ae94</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="1">https://ws.ebs.health.gov.on.ca:1441/EDTService/EDTService</a:To>
</s:Header>

В этом сообщении у нас появляются необходимые заголовки EBS и IDP, но исчезает Security.

И пока мне не понятно как сделать так, чтобы подогнать мое soap сообщение к нужному. Может хоть кто подскажет что я делаю не так. 
Я так понимаю что нужно CustomBinding создавать и как-то настраивать. 
И MessageCredentialType должен быть Certificate?

Буду рад любой помощи/подсказкам. Спасибо.

Автор: jonie 25.10.2013, 10:37
а там что требуется клиентский сертификат? Я вот открыл адресок  https://ws.ebs.health.gov.on.ca:1441/EDTService/ и собственно получил ответ без всяких клиентских сертификатов...

Автор: MFSham 25.10.2013, 11:40
Ну судя про правильному SOAP сообщению и наличии в нем элемента BinarySecurityToken сертификат нужне для подписи.
И еще из спецификации по подключению (что необходимо):
Цитата

Signature
Digital signature that adheres to the signing requirements specified below.

Автор: jonie 25.10.2013, 12:56
Цитата(MFSham @  25.10.2013,  12:40 Найти цитируемый пост)
Ну судя про правильному SOAP сообщению и наличии в нем элемента BinarySecurityToken сертификат нужне для подписи.

ну подписание сообщения это подписание сообщения....

надо копать в сторону кастомного биндинга типа такого http://stackoverflow.com/questions/13226188/how-do-i-sign-a-binarysecuritytoken-in-soap-message


Автор: borisd 11.12.2013, 19:17
У меня тоже стоит задача по написанию WCF клиента для этого сервиса.
И тоже столкнулся с непонятным поведением, правда уже при парсинге подписанного и зашифрованого ответа.
ДотНет выдает странную ошибку:
The EncryptedKey clause was not wrapped with the required encryption token 'System.IdentityModel.Tokens.X509SecurityToken'.

Хотя в фидлере все выглядит очень похоже на ожидаемый ответ этого сервиса.

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/Правильное-подключение-к-WCF-веб-сервису.-id526935f2ae20151f53000000#findElement_E7045_52a88ffeae2015eb3a9d4da0_0

Автор: kazaczok 19.12.2013, 16:57
Аналогичная задача стоит и у меня по данному сервису. У кого-нибудь получилось построить корректный вызов?

Автор: borisd 5.2.2014, 11:11
У меня получилось обрабатывать обычные ответы сервиса.
Сейчас бьюсь с download, когда файлы приходят в multipart виде и как правильно расшифровать все это, а потом собрать SOAP сообщение.

Если, что пишите в личку свои контактные данные и зашарюб вариант своего решения.

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/Правильное-подключение-к-WCF-веб-сервису-id526935f2ae20151f53000000#findElement_E7045_52f1f239ae2015f0438b45df_0

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)