Какую платформу программирования следует использовать для использования службы SOAP с WS-Security?

Мне нужно использовать веб-службу SOAP 1.2, которая использует WS-Security. В работе я использую Delphi 10.2 Tokyo и .Net Core. Ни один из них, похоже, не работает.

  • Я делаю что-то не так при использовании веб-сервисов?
  • Если нет, то каковы другие альтернативы для платформ? Я открыт для любых предложений. С максимально возможной встроенной поддержкой приведенного ниже WSDL. Приложение, которое я создаю, должно быть приложением для Windows.

При попытке использовать встроенный в Delphi 10.2 Tokyo импортер WSDL (с использованием SOAP 1.2 с Indy) мои запросы отправляются без какой-либо информации заголовка SOAP. Этот недопустимый запрос вызывает ошибку Сброс соединения пиром.

При попытке с .Net Core (с использованием поставщика ссылок на веб-службы WCF) я получаю сообщение об ошибке: System.PlatformNotSupportedException: «TransportSecurityBindingElement.BuildChannelFactoryCore не поддерживается».

Предположительно из-за того, что требуемая функция еще не поддерживается .Net Core: https://github.com/dotnet/wcf/blob/master/release-notes/SupportedFeatures-v2.0.0.md (Security.Message не поддерживается)

Ниже приведен WSDL. Я удалил ненужный XML из этого файла и заменил фактическое название компании на Example. Надеюсь, это даст достаточное представление о политиках/требованиях WSDL.

<?xml version = "1.0" encoding = "UTF-8"?>
<wsdl:definitions
    xmlns:wsdl = "http://schemas.xmlsoap.org/wsdl/"
    xmlns:i0 = "http://tempuri.org/"
    xmlns:msc = "http://schemas.microsoft.com/ws/2005/12/wsdl/contract"
    xmlns:soap = "http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:soap12 = "http://schemas.xmlsoap.org/wsdl/soap12/"
    xmlns:soapenc = "http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:tns = "www.example.com/ExampleService"
    xmlns:wsa = "http://schemas.xmlsoap.org/ws/2004/08/addressing"
    xmlns:wsa10 = "http://www.w3.org/2005/08/addressing"
    xmlns:wsam = "http://www.w3.org/2007/05/addressing/metadata"
    xmlns:wsap = "http://schemas.xmlsoap.org/ws/2004/08/addressing/policy"
    xmlns:wsaw = "http://www.w3.org/2006/05/addressing/wsdl"
    xmlns:wsp = "http://schemas.xmlsoap.org/ws/2004/09/policy"
    xmlns:wsu = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
    xmlns:wsx = "http://schemas.xmlsoap.org/ws/2004/09/mex"
    xmlns:xsd = "http://www.w3.org/2001/XMLSchema"
    name = "ExampleService"
    targetNamespace = "www.example.com/ExampleService">
    <wsp:Policy wsu:Id = "ExampleAPI_policy">
        <wsp:ExactlyOne>
            <wsp:All>
                <sp:TransportBinding xmlns:sp = "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
                    <wsp:Policy>
                        <sp:TransportToken>
                            <wsp:Policy>
                                <sp:HttpsToken RequireClientCertificate = "false" />
                            </wsp:Policy>
                        </sp:TransportToken>
                        <sp:AlgorithmSuite>
                            <wsp:Policy>
                                <sp:Basic256 />
                            </wsp:Policy>
                        </sp:AlgorithmSuite>
                        <sp:Layout>
                            <wsp:Policy>
                                <sp:Strict />
                            </wsp:Policy>
                        </sp:Layout>
                        <sp:IncludeTimestamp />
                    </wsp:Policy>
                </sp:TransportBinding>
                <sp:EndorsingSupportingTokens xmlns:sp = "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
                    <wsp:Policy>
                        <sp:SecureConversationToken sp:IncludeToken = "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
                            <wsp:Policy>
                                <sp:BootstrapPolicy>
                                    <wsp:Policy>
                                        <sp:SignedParts>
                                            <sp:Body />
                                            <sp:Header Name = "To" Namespace = "http://www.w3.org/2005/08/addressing" />
                                            <sp:Header Name = "From" Namespace = "http://www.w3.org/2005/08/addressing" />
                                            <sp:Header Name = "FaultTo" Namespace = "http://www.w3.org/2005/08/addressing" />
                                            <sp:Header Name = "ReplyTo" Namespace = "http://www.w3.org/2005/08/addressing" />
                                            <sp:Header Name = "MessageID" Namespace = "http://www.w3.org/2005/08/addressing" />
                                            <sp:Header Name = "RelatesTo" Namespace = "http://www.w3.org/2005/08/addressing" />
                                            <sp:Header Name = "Action" Namespace = "http://www.w3.org/2005/08/addressing" />
                                        </sp:SignedParts>
                                        <sp:EncryptedParts>
                                            <sp:Body />
                                        </sp:EncryptedParts>
                                        <sp:TransportBinding>
                                            <wsp:Policy>
                                                <sp:TransportToken>
                                                    <wsp:Policy>
                                                        <sp:HttpsToken RequireClientCertificate = "false" />
                                                    </wsp:Policy>
                                                </sp:TransportToken>
                                                <sp:AlgorithmSuite>
                                                    <wsp:Policy>
                                                        <sp:Basic256 />
                                                    </wsp:Policy>
                                                </sp:AlgorithmSuite>
                                                <sp:Layout>
                                                    <wsp:Policy>
                                                        <sp:Strict />
                                                    </wsp:Policy>
                                                </sp:Layout>
                                                <sp:IncludeTimestamp />
                                            </wsp:Policy>
                                        </sp:TransportBinding>
                                        <sp:SignedSupportingTokens>
                                            <wsp:Policy>
                                                <sp:UsernameToken sp:IncludeToken = "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
                                                    <wsp:Policy>
                                                        <sp:WssUsernameToken10 />
                                                    </wsp:Policy>
                                                </sp:UsernameToken>
                                            </wsp:Policy>
                                        </sp:SignedSupportingTokens>
                                        <sp:Wss11>
                                            <wsp:Policy />
                                        </sp:Wss11>
                                        <sp:Trust10>
                                            <wsp:Policy>
                                                <sp:MustSupportIssuedTokens />
                                                <sp:RequireClientEntropy />
                                                <sp:RequireServerEntropy />
                                            </wsp:Policy>
                                        </sp:Trust10>
                                    </wsp:Policy>
                                </sp:BootstrapPolicy>
                            </wsp:Policy>
                        </sp:SecureConversationToken>
                    </wsp:Policy>
                </sp:EndorsingSupportingTokens>
                <sp:Wss11 xmlns:sp = "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
                    <wsp:Policy />
                </sp:Wss11>
                <sp:Trust10 xmlns:sp = "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
                    <wsp:Policy>
                        <sp:MustSupportIssuedTokens />
                        <sp:RequireClientEntropy />
                        <sp:RequireServerEntropy />
                    </wsp:Policy>
                </sp:Trust10>
                <wsaw:UsingAddressing />
            </wsp:All>
        </wsp:ExactlyOne>
    </wsp:Policy>
    <wsp:Policy wsu:Id = "ExampleAPI2_policy">
        <wsp:ExactlyOne>
            <wsp:All>
                <sp:TransportBinding xmlns:sp = "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
                    <wsp:Policy>
                        <sp:TransportToken>
                            <wsp:Policy>
                                <sp:HttpsToken RequireClientCertificate = "false" />
                            </wsp:Policy>
                        </sp:TransportToken>
                        <sp:AlgorithmSuite>
                            <wsp:Policy>
                                <sp:Basic256 />
                            </wsp:Policy>
                        </sp:AlgorithmSuite>
                        <sp:Layout>
                            <wsp:Policy>
                                <sp:Lax />
                            </wsp:Policy>
                        </sp:Layout>
                        <sp:IncludeTimestamp />
                    </wsp:Policy>
                </sp:TransportBinding>
                <sp:SignedSupportingTokens xmlns:sp = "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
                    <wsp:Policy>
                        <sp:UsernameToken sp:IncludeToken = "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
                            <wsp:Policy>
                                <sp:WssUsernameToken10 />
                            </wsp:Policy>
                        </sp:UsernameToken>
                    </wsp:Policy>
                </sp:SignedSupportingTokens>
                <sp:Wss10 xmlns:sp = "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
                    <wsp:Policy />
                </sp:Wss10>
            </wsp:All>
        </wsp:ExactlyOne>
    </wsp:Policy>
    <wsdl:types>

        <!-- trimmed away types -->

    </wsdl:types>

    <!-- trimmed away messages -->

    <wsdl:portType name = "IAPIService">

        <!-- trimmed away operations -->

    </wsdl:portType>
    <wsdl:binding name = "ExampleAPI" type = "tns:IAPIService">
        <wsp:PolicyReference URI = "#ExampleAPI_policy" />
        <soap12:binding transport = "http://schemas.xmlsoap.org/soap/http" />

        <!-- trimmed away operations -->

    </wsdl:binding>
    <wsdl:binding name = "ExampleAPI2" type = "tns:IAPIService">
        <wsp:PolicyReference URI = "#ExampleAPI2_policy" />
        <soap:binding transport = "http://schemas.xmlsoap.org/soap/http" />

        <!-- trimmed away operations -->

    </wsdl:binding>
    <wsdl:service name = "ExampleService">
        <wsdl:port name = "ExampleAPI" binding = "tns:ExampleAPI">
            <soap12:address location = "https://example.com/apps/api/APIService.svc" />
            <wsa10:EndpointReference>
                <wsa10:Address>https://example.com/apps/api/APIService.svc</wsa10:Address>
            </wsa10:EndpointReference>
        </wsdl:port>
        <wsdl:port name = "ExampleAPI2" binding = "tns:ExampleAPI2">
            <soap:address location = "https://example.com/apps/api/APIService.svc/endpoint2" />
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
348
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Не существует конкретной «лучшей» платформы для использования веб-сервиса. Однако некоторые платформы лучше других поддерживают автоматическую генерацию прокси-классов.

When trying with Delphi 10.2 Tokyo's built in WSDL importer (using SOAP 1.2 with Indy), my requests are sent without any SOAP header information.

У меня нет опыта работы с .NET Core, но при использовании Delphi 10.2 вам необходимо вручную добавить (отправить) заголовок SOAP перед отправкой запроса.

Это можно сделать, приведя экземпляр веб-сервиса к ISOAPHeaders

Пример:

procedure TestSendHeader;
var
  MyService: IMySoapWebservice;
  header : TMySoapHeader;
begin
  MyService := GetMySoapService();
  (MyService as ISOAPHeaders).OwnsSentHeaders := True;

  // Create header object
  header := TMySoapHeader.Create;
  // Fill header data
  // header.xyz := ;
  // 'Send' header with the request
  (MyService as ISOAPHeaders).Send(header);

  MyResponse := MyService.DoMyRequest();
end;

Установка OwnsSentHeaders на true освободит созданный объект заголовка после отправки запроса.

ПРИМЕЧАНИЕ: вы должны «Отправить» заголовок каждый раз, когда делаете запрос:

  // 'Send' header with the request 1
  (MyService as ISOAPHeaders).Send(header);    
  MyResponse := MyService.DoMyRequest1();

  // 'Send' header with the request 2
  (MyService as ISOAPHeaders).Send(header);    
  MyResponse := MyService.DoMyRequest2();

В этом случае не устанавливайте OwnsSentHeaders на true и освобождайте объект заголовка после того, как вы закончите отправку запросов.

Означает ли это, что мне придется самостоятельно реализовывать функции WS-Security и WS-Addressing? Кажется, что это огромная задача, поскольку она включает в себя шифрование, подпись данных и т. д. Может быть, кто-то уже проделал тяжелую работу и выложил ее на GitHub? Хотя ничего не нашел...

P. Bergström 30.05.2019 17:28

У меня есть некоторый код, относящийся к базовой структуре WS-безопасности (xml-объект), который я посмотрю завтра. Но шифрование данных (кодировка base64) не является частью этого, поэтому вы должны сделать это самостоятельно.

R. Hoek 30.05.2019 22:33

Я разместил код Delphi, касающийся заголовка WS-Security. Обратите внимание, что есть две версии (по крайней мере, о которых я знаю) - 2003.06 и 2004.01. Оба добавлены в суть: gist.github.com/ronaldhoek/ff7611a0b4bd03c01f72c3dd5a4f0a5c

R. Hoek 31.05.2019 13:02

Что касается кодирования, в Delphi есть модуль под названием «System.NetEncoding» (начните с Delphi 10 или около того), который поможет в кодировании/декодировании данных.

R. Hoek 31.05.2019 13:03

Спасибо большое. Я посмотрю на WS-безопасность в Delphi, когда у меня будет свободное время. Выглядит многообещающе. Тем временем я решил заняться разработкой .NET Framework DLL, которую может использовать Delphi.

P. Bergström 02.06.2019 17:16
Ответ принят как подходящий

.NET Framework полностью поддерживает службу SOAP. Я разработал приложение .NET Framework на C# и создал библиотеку DLL, которую можно использовать в Delphi, .NET Core и т. д. Это немного окольное решение, но самое простое, которое я смог найти.

Доступ к службам на C#: https://docs.microsoft.com/en-us/dotnet/framework/wcf/accessing-services-using-a-wcf-client

Экспорт функций DLL: Можно ли экспортировать функции из C# DLL, как в VS C++?

Другие вопросы по теме