CXF - Zabezpieczenie usług za pomocą WS-Security
Autor: Marcin Kasiński
23.11.2012 21:41:49 +0200
W poniższym artykule postaram się opisać konfiguracje bezpiecznej komunikacji z użyciem CXF i WS-Security. Zakładam, że czytający artykuł ma podstawową wiedzę o tym jak zbudować prostą usługę CXF oraz klienta CXF. W artykule opisane będą następujące technologie:
- cxf
- Spring Framework
- WSS4J
W przykładzie poniższym klient zabezpiecza wysłane zapytanie XML poprzez jego zaszyfrowanie oraz podpisanie. Usługa CXF podczas weryfikacji sprawdza podpis i odkodowuje komunikat. W naszym przykładzie opisze konfiguracje z wykorzystaniem certyfikatów oraz UsernameToken.
Zabezpieczenie usługi
W przypadku usługi będziemy walidowali zapytanie klienta. Aby to zrobić musimy w definicji usługi zdefiniować interceptor wejściowy. Oznacza to, że przy próbie wywołania usługi usługa wywoła kod zaimplementowany w interceptorze. W naszym przypadku interceptorem będzie biblioteka WSS4J.
<jaxws:endpoint ... > ... <jaxws:inInterceptors> <ref bean="RequestInterceptor" /> </jaxws:inInterceptors> <!-- <jaxws:outInterceptors> <ref bean="ResponseInterceptor" /> </jaxws:outInterceptors> --> </jaxws:endpoint>
Zabezpieczenie klienta
W przypadku klienta będziemy przed wysłaniem zapytania modyfikowali zapytanie XML o część związaną z bezpieczeństwem. Aby to zrobić musimy w definicji usługi zdefiniować interceptor wyjściowy. Oznacza to, że przy próbie wysłania zapytania klient wywoła kod zaimplementowany w interceptorze.
<jaxws:client ...> ... <jaxws:outInterceptors> <ref bean="RequestInterceptor" /> </jaxws:outInterceptors> </jaxws:client>
Certyfikat X.509
Za pomocą certyfikatów możemy dokonać operacji szyfrowania, odszyfrowania oraz podpisywania komunikatów lub ich części. Tu skupimy się tylko i wyłącznie na konfiguracji Spring usługi i klienta. Sama konfiguracja bazy certyfikatów opisana została w innym artykule.
Zabezpieczenie usługi Certyfikat X.509
Pierwszym interceptorem jaki chce opisać będzie kod obsługujący zabezpieczenia za pomocą certyfikatów X.509. W dalszej części w interceptorze określimy jakie czynności powinny być wykonane przed uruchomieniem usługi. Poniżej znajduje się przykładowa konfiguracja interceptora wejściowego naszej usługi.
<bean id="RequestInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"> <constructor-arg> <map> <entry key="action" value="Timestamp Signature Encrypt"/> <entry key="signaturePropFile" value="server_sign.properties"/> <entry key="decryptionPropFile" value="server_sign.properties"/> <entry key="passwordCallbackClass" value="mkcallbackpackage.ServiceKeystorePasswordCallback"/> </map> </constructor-arg> </bean>
Ważniejsze parametry interceptora usługi:
Parametr | Opis |
---|---|
action | akcja, jaka będzie wykonywana podczas wymiany komunikacji pomiędzy klientem, a serwerem, np, Timestamp Signature Encrypt . W naszym przykładzie użyjemy wszystkich akcji jednocześnie |
signaturePropFile | plik opisujący parametry bezpieczeństwa związane z podpisywaniem komunikatów |
decryptionPropFile | plik opisujący parametry bezpieczeństwa związane z odszyfrowaniem komunikatów |
passwordCallbackClass | klasa pozwalająca na dynamiczne pobranie hasła dla danego użytkownika |
Klasa do obsługi passwordCallback może pobierać hasła z różnych dowolnych repozytoriów, DB, LDAP, plik itp. W naszej przykładowej klasie hasło ustawimy manualnie bezpośrednio w klasie.
package mkcallbackpackage; import java.io.IOException; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import org.apache.ws.security.WSPasswordCallback; public class ServiceKeystorePasswordCallback implements CallbackHandler { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; int usage = pc.getUsage(); if (usage == WSPasswordCallback.USERNAME_TOKEN) { if (pc.getIdentifier().equals("myuser")) pc.setPassword("mypassword"); } else { if ((usage != WSPasswordCallback.SIGNATURE) && (usage != WSPasswordCallback.DECRYPT)) continue; // System.out.println("pc.getIdentifier() " + pc.getIdentifier()); pc.setPassword("passwordserverjks"); } } } }
Przykładowy plik konfiguracyjny serwisu znajduje się poniżej. Opisuje on podstawowe parametry bazy kluczy używane przy komunikacji.
org.apache.ws.security.crypto.merlin.keystore.type=jks org.apache.ws.security.crypto.merlin.keystore.password=passwordserverjks org.apache.ws.security.crypto.merlin.file=itzone.jks
Zabezpieczenie klienta Certyfikat X.509
Po stronie klienta musimy w naszym interceptorze wyjściowym ustawić parametry opisujące nasze zapytanie WS-Security
<bean id="RequestInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor"> <constructor-arg> <map> <!-- <entry key="action" value="Timestamp Signature Encrypt"/> --> <entry key="action" value="Timestamp Signature Encrypt"/> <entry key="user" value="client" /> <entry key="signaturePropFile" value="client_sign.properties"/> <entry key="encryptionPropFile" value="client_encrypt.properties"/> <entry key="encryptionUser" value="server cert" /> <entry key="signatureKeyIdentifier" value="DirectReference"/> <entry key="signatureParts" value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body"/> <!-- <entry key="encryptionParts" value="{Element}{http://www.w3.org/2000/09/xmldsig#}Signature;{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body"/> --> <entry key="encryptionParts" value="{Element}{http://www.w3.org/2000/09/xmldsig#}Signature;{Content}{Null}arg0"/> <entry key="encryptionSymAlgorithm" value="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/> <entry key="passwordCallbackClass" value="mkcallbackpackage.ServiceKeystorePasswordCallback"/> </map> </constructor-arg> </bean>
Ważniejsze parametry interceptora klienta:
Parametr | Opis |
---|---|
action | akcja, jaka będzie wykonywana podczas wymiany komunikacji pomiędzy klientem, a serwerem, np, Timestamp Signature Encrypt . W naszym przykładzie użyjemy wszystkich akcji jednocześnie |
user | alias wykorzystywanego z bazy klucza |
signaturePropFile | plik opisujący parametry bezpieczeństwa związane z podpisywaniem komunikatów |
encryptionPropFile | plik opisujący parametry bezpieczeństwa związane z zaszyfrowaniem komunikatów |
encryptionUser | alis klucza, którym nastąpi zaszyfrowanie komunikatu |
signatureKeyIdentifier | Sposób przekazania certyfikatu klienta do serwera.W naszym przypadku cały certyfikat będzie wysłąny w komunikacie |
signatureParts | część komunikatu jaka będzie podpisana |
encryptionParts | część komunikatu jaka będzie podpisana. Wnaszym przypadku będzie to podpis i zawartość taga "arg0" |
encryptionSymAlgorithm | algorytm szyfrowania komunikatu |
passwordCallbackClass | klasa pozwalająca na dynamiczne pobranie hasła dla danego użytkownika |
Klasa do obsługi passwordCallback może pobierać hasła z różnych dowolnych repozytoriów, DB, LDAP, plik itp. W naszej przykładowej klasie hasło ustawimy manualnie bezpośrednio w klasie. Klasa ta prawie dokładnie wygląda tak samo jak klasa serwisu. Różnią się one tylko i wyłącznie hasłem generowanym w klasie.
package mkcallbackpackage; import java.io.IOException; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import org.apache.ws.security.WSPasswordCallback; public class ServiceKeystorePasswordCallback implements CallbackHandler { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; int usage = pc.getUsage(); if (usage == WSPasswordCallback.USERNAME_TOKEN) { if (pc.getIdentifier().equals("myuser")) pc.setPassword("mypassword"); } else { if ((usage != WSPasswordCallback.SIGNATURE) && (usage != WSPasswordCallback.DECRYPT)) continue; System.out.println("pc.getIdentifier() " + pc.getIdentifier()); pc.setPassword("passwordjks"); } } } }
Przykładowy plik konfiguracyjny klienta znajduje się poniżej. Opisuje on podstawowe parametry bazy kluczy używane przy komunikacji analogicznie , jak to ma miejsce w konfiguracji serwisu.
org.apache.ws.security.crypto.merlin.keystore.type=jks org.apache.ws.security.crypto.merlin.keystore.password=passwordjks org.apache.ws.security.crypto.merlin.file=in/client.jks
Poniżej zapytanie wygenerowane z naszej przykładowej aplikacji klienckiej.
POST /HelloImplWeb/services/HelloMgrImplPort HTTP/1.1 Content-Type: text/xml; charset=UTF-8 Accept: */* Authorization: Basic dG9tY2F0OnRvbWNhdA== SOAPAction: "urn:Hello" User-Agent: Apache CXF 2.7.0 Cache-Control: no-cache Pragma: no-cache Host: 127.0.0.1:9091 Connection: keep-alive Transfer-Encoding: chunked ff9 <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header> <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" soap:mustUnderstand="1"> <xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="EK-51CD693A50FB309D8A13543728589124"> <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> <ds:X509Data> <ds:X509IssuerSerial> <ds:X509IssuerName>CN=tomcat server,OU=IT,O=IT Zone,L=WAW,C=PL</ds:X509IssuerName> <ds:X509SerialNumber>1338233808</ds:X509SerialNumber> </ds:X509IssuerSerial> </ds:X509Data> </wsse:SecurityTokenReference> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherValue>FbpuQnusITNFpPlPzzm9LkMsZBnJvUErVgCY34KTo47gNbpr4L7LfFdftABOe5jmxf1hSMLu7wtfOFLg5o0ovzpFgrHfQc3rUExcy+8SA5mAIqFamySDVGYOfN4v4BXSV540ZZhGqa2E6n5RIX4474cemfuKhfIuYXae+BfxJI8=</xenc:CipherValue> </xenc:CipherData> <xenc:ReferenceList> <xenc:DataReference URI="#ED-4"/> <xenc:DataReference URI="#ED-5"/> </xenc:ReferenceList> </xenc:EncryptedKey> <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-51CD693A50FB309D8A13543728587241">MIIB8zCCAVygAwIBAgIEUK83NTANBgkqhkiG9w0BAQUFADA+MQswCQYDVQQGEwJQTDEMMAoGA1UEBxMDV0FXMRAwDgYDVQQKEwdJVCBab25lMQ8wDQYDVQQDEwZjbGllbnQwHhcNMTIxMTIzMDg0MzMzWhcNMTMxMTIzMDg0MzMzWjA+MQswCQYDVQQGEwJQTDEMMAoGA1UEBxMDV0FXMRAwDgYDVQQKEwdJVCBab25lMQ8wDQYDVQQDEwZjbGllbnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJKfyNhu0yTeu3gw8jBdqNx6CXvnpQFZt9gswwGq6ZLjXZqZKZhT+zDgK/XDJh+nLxdVTPXLlIfHKl9miHU+jjSUVRYrsGMqw3ajmJxR7ulrH7SjFzpX/xnk/gtnWKAXdUYCZMH/laubZ+ipCMfxXpLYDDRCI1YIT5sdziUg60APAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAOv0W0oS/L3O3DXimGYb0Ar4D28Br2tNC6kuqj1PvjEq5FUKOreaGuek8MC/DaFtNURZIMD1F3dPQC2VHavOPzfnwiqyuvxVKThBZzWz+36KhedsMgBBvnmZ9X7Lr8AKgpmSz0J+Vpxne+SoXzT3LegXuNjI0Em1tMie5DBEOwXU=</wsse:BinarySecurityToken> <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="ED-4" Type="http://www.w3.org/2001/04/xmlenc#Element"> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-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" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey"> <wsse:Reference URI="#EK-51CD693A50FB309D8A13543728589124"/> </wsse:SecurityTokenReference> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherValue>/HuA5GT3X+lEYboPwtyTMD/U+LEaYQhqDef/QGsSC6gXm0el0C51/vRASpfz+aQIvk0oIHsMTE31jpW3ajqHAOVtvCPq53f/lD1MRceSmMLX+yQ6sfXovK+bt7rGhGPuiWtFXSHYGnpOGcABNP9tJ9ir+jof5R4GthPHmFgFc7c1W7dmUaQWAgvftF1WSAJdUkkEP5BmYM8MvdupH9SKvKakox/qLPr8qX2YnXR2DkuvxblfGV9GitFPBfCYZm0Eb/LcNzIqjV+hgPuOKiwQlEHfhlrffPw5tiFB6ENLA+4Pw17dJD6V40Mpuh99l4ULPIDtdbzHUe0Ui/GrR9PXFoFoAEgfKP7CmkXZU7Hhi44Q3Utv7jiL6rAY7CPQI7sctnBJ2RIQSnmfobDsSbMCTJ2tjXib60wM9zXMiF3JOO7m4Ai41unsEUg41Zv7rrpL2+jd+dkLxbduL672YgcN1UuJXJpNr5ECiX9cr7qYyCxTFGW+/8VhP9RisAFv5xQJ5bQ2e2VTdbBlEa1sIGsAjOWs+CAwKiZydT+CvZUIV9xLVAmlQuK1ewuTmhamjXat7frXm8fF+4XP+jQ1bFBoU5f4evtyVZZSkb8bihfOlKZUMiWMHY32hDRqZyeOqmpwXRlgQO7xwvn99jx5wRFrOcsQfU8vb/JjjsGPEalBp7nTIRnpl3yB4Qa9MwzAW+RVfk1MXpKHtyQIzV0zJ4AYsuhZRxZ6H7nbr0wjBRqriiUYaKAIoGVVPiT2r3oDlfooEtfFO9GdEFh/SerLapT/VtRych1l0LmlWEnBNNWRflDaw7gla5aovU1B60/L30DyHnEHZ/yr0c1Hw70hF2aKm4OjsY3JQrE0is9GzS8whFtlVrnYr8TyoYtOSbIZPuqp3qxEn/oBnlLOPGSr5yF18tBVraiCd4HcFi4m2w3pU7k2zKS9DB1SC8se5iHSbkYSqAIqzt5gW53njVUL6EJj9Bo/9+hDJSe579QcNhtUKD4fFkz+s54TIBASRmtIjRgnwEMkYI1PBkqgLpgNzT4VLnei9nPOH4MyzTF0bAH1tyemo+3k8vmksOkKKfpwL1J2kE0jW2NIjXuF6DlVJMUWSXnLIRbXisUI7OoCTVhrO4B6h/rn7P28V8K3trvL1ZTRVeRXv43NomB1W8MNbnU2W3yR+Or1KUVaG/oCGo+p5/N26f 9ca 4yXDmcS10eCnJ5ygxfcRW13SJFN/Q7djHBAGqL1mxOK6GVffsHAcdySi2xsf3DGMqjyKmMrhi/6pgW90mGdwZqAk7FIo65pv8Zta9abguqHVrCgRcvgxHBfyW5HVvFVQc1OUH3pKJk8MUF2EFZ0x2H6XiOVAUR5Pj70xKlDDIFEKj2NrcIsuyn2KGDU2ystyDZdEN8J3btLk2CHVohL8SYXJ3oiXaLQV1lu+dDU0f3v7HDWbJdX3BCB3RlYf8i3QnibJ7lS8pA6bzltF6KlOKGT8J9VEfLxd727axZtGKQ8KSg0TL51P0aNc4/Mg1ryPdpLdhkAH8ocC3ZwcZPxefCA1YztINumGANImDV+KiNNcuYIayvROwiEw8o69s/22kdC0L0Oy5Zfab8mEKqoIdIVGHXmkrgW4QNDIhgolO30hYGK5Ytaryak3UzYyEux5GIk6kyhWmHN1ScQn23aWZzUBqPMq0subN+uBPXp1eQZlcDK3jAH/RMAZzkoLJyfYk3p9BgRUqBwoNOV79r04RfRjzwbPbojbvxg8g8sV6r0/fUfpygCvLVCoE64KPlQW0c8kJy7ECZdM/fHwSdpMQAbHFKgGW9snpNp10rbluVC2qluZhkwQxGG+mZ2PsTwosl7ih9g5K7CD4xeyZoIW9yohWFxy5uQUUliYyXf2Ql4aDAEzpV1Pxsybsi7C25+gG/o20cqMKCxMgYbHmvmNWsvCIpl3uDblPgVsSRsxF/5/pdW4eoz0akC7/6TLGtg6ezCnZO8zmQe7V2+b72/us99Z2LrCEO3G0j4N2tiFppxTq4dv5QX/SQRLMFubTNoW6TVlAbPIuXA6eOLsX0/JRYhDCH6v1Y/IzHvUQlnZaiZGAGLci83uYyKoJMWNPGl/oojy2kyN2tLLHN+Zgu7YhX5dZgJYdJg7xwC/DZjHOR07TVZ9J47Z8KZWP5pnQU2e68ye6/D8lYXAt1LkjE9yOJ39TJHxfTd6dMDuxhsK1/5zdZFO7COQKU+awsTkWVQ1Ttlev910Odierc0hEU4ddlHwtH2fWpeZegUO6D4I6yGlDo+4jI93IA8H4ATpO8Z9WwwOtk8ftuiCY8p+Now7ZZS5aXmphPFCqqxDOeLuAHupdHLd0FFTqdvK+/aTWWoUmt/Apr1vI17j2kybYuJjJMM3x/9i9Euenuw/8q3MZWVwbsThoEDxgchlLyxqELNIEwEpDs4H6KVJ9FHYbmy1nUyBVLzcjUGffD1P0IAYTBplu6td3e</xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedData> <wsu:Timestamp wsu:Id="TS-1"> <wsu:Created>2012-12-01T14:40:58.708Z</wsu:Created> <wsu:Expires>2012-12-01T14:45:58.708Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soap:Header> <soap:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-2"> <ns2:hello xmlns:ns2="http://mkpackage/"> <arg0> <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="ED-5" Type="http://www.w3.org/2001/04/xmlenc#Content"> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-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" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey"> <wsse:Reference URI="#EK-51CD693A50FB309D8A13543728589124"/> </wsse:SecurityTokenReference> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherValue>1B9FOfzawZJ5XzTh49RyWQ==</xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedData> </arg0> </ns2:hello> </soap:Body></soap:Envelope>0
UsernameToken
W przypadku zabezpeiczenia UsernameToken od strony serwerowej weryfikujemy login i hasło podane przez wywołującego usługę. Jest to dość prostę zabezpeiczenie i nie zapewnia zbyt dużego poziomu bezpieceństwa.
Zabezpieczenie usługi UsernameToken
<bean id="RequestInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"> <constructor-arg> <map> <entry key="action" value="UsernameToken Timestamp" /> <!-- <entry key="passwordType" value="PasswordText" /> --> <entry key="passwordType" value="PasswordDigest" /> <entry key="passwordCallbackClass" value="mkcallbackpackage.ServiceKeystorePasswordCallback" /> </map> </constructor-arg> </bean>
Zabezpieczenie klienta UsernameToken
<bean id="RequestInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor"> <constructor-arg> <map> <entry key="action" value="UsernameToken Timestamp" /> <entry key="user" value="myuser" /> <!-- <entry key="passwordType" value="PasswordText" /> --> <entry key="passwordType" value="PasswordDigest" /> <entry key="passwordCallbackClass" value="mkcallbackpackage.ServiceKeystorePasswordCallback" /> </map> </constructor-arg> </bean>
Poniżej zapytanie wygenerowane z naszej przykładowej aplikacji klienckiej.
POST /HelloImplWeb/services/HelloMgrImplPort HTTP/1.1 Content-Type: text/xml; charset=UTF-8 Accept: */* Authorization: Basic dG9tY2F0OnRvbWNhdA== SOAPAction: "urn:Hello" User-Agent: Apache CXF 2.7.0 Cache-Control: no-cache Pragma: no-cache Host: 127.0.0.1:9091 Connection: keep-alive Content-Length: 1077 <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header> <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" soap:mustUnderstand="1"> <wsu:Timestamp wsu:Id="TS-2"> <wsu:Created>2012-11-23T20:39:40.777Z</wsu:Created> <wsu:Expires>2012-11-23T20:44:40.777Z</wsu:Expires> </wsu:Timestamp> <wsse:UsernameToken wsu:Id="UsernameToken-1"> <wsse:Username>myuser</wsse:Username> <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">DSeFawMsrfgzLTguI1BB7udU1xU=</wsse:Password> <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">8fh3c+hrfP7Xh4qE7UYeHQ==</wsse:Nonce> <wsu:Created>2012-11-23T20:39:40.777Z</wsu:Created> </wsse:UsernameToken> </wsse:Security> </soap:Header> <soap:Body> <ns2:hello xmlns:ns2="http://mkpackage/"> <arg0>Marcin</arg0> </ns2:hello> </soap:Body></soap:Envelope> powrót
Komentarze
firma 24
<a href="https://ogloszeniaswietokrzyskie.pl/firmy">firma 24</a>|
ihugu 2023-03-20 09:05:02
własna firma
<a href="https://zachodniopomorskieogloszenia.pl/firmy">własna firma</a>|
idotip 2023-03-17 19:20:24
jaki hosting na bloga
<a href="https://dobry-serwer.ovh">jaki hosting na bloga</a>
oheco 2023-03-04 17:59:44
serwer co to
<a href="https://tani-serwer.ovh">serwer co to</a>
ifygys 2022-11-02 18:24:34
http://informacjesosnowiec.pl/kategoria/Profilaktyka
Informacje Sosnowiec <a href="http://informacjesosnowiec.pl/kategoria/Profilaktyka">http://informacjesosnowiec.pl/kategoria/Profilaktyka</a>
afomuh 2022-10-15 19:27:59
chirurg
<a href="https://bliskilekarz.pl/chirurg">chirurg</a>
ecigohone 2022-04-23 03:12:09
Dodaj Komentarz
Newsletter
Jeżeli chcesz być na bieżąco informowany o aktualnościach i poradach IT zapisz się do naszego newslettera.