【问题标题】:Which programming platform should I use to consume a SOAP service with WS-Security?我应该使用哪个编程平台来使用 WS-Security 的 SOAP 服务?
【发布时间】:2019-05-30 12:54:17
【问题描述】:

我需要使用一个使用 WS-Security 的 SOAP 1.2 Web 服务。我在工作中使用的平台是 Delphi 10.2 Tokyo 和 .Net Core。这些似乎都不起作用。

  • 我在使用 Web 服务时是否做错了什么?
  • 如果不是,我还有哪些其他平台替代方案?我愿意接受任何建议。尽可能多地内置对以下 WSDL 的支持。我正在构建的应用必须是 Windows 应用。

当尝试使用 Delphi 10.2 Tokyo 的内置 WSDL 导入器(使用带有 Indy 的 SOAP 1.2)时,我的请求在没有任何 SOAP 标头信息的情况下发送。此无效请求引发错误Connection reset by peer

尝试使用 .Net Core(使用 WCF Web 服务参考提供程序)时出现错误:System.PlatformNotSupportedException: 'TransportSecurityBindingElement.BuildChannelFactoryCore is not supported.'

可能是由于 .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>

【问题讨论】:

    标签: .net delphi asp.net-core soap ws-security


    【解决方案1】:

    没有特定的“最佳”平台来使用 Web 服务。 但是,某些平台比其他平台更好地支持代理类的自动生成。

    当尝试使用 Delphi 10.2 Tokyo 的内置 WSDL 导入器(使用带有 Indy 的 SOAP 1.2)时,我的请求在没有任何 SOAP 标头信息的情况下发送。

    我没有使用 .NET Core 的经验,但是在使用 Delphi 10.2 时,您需要在发送请求之前手动添加(发送)SOAP 标头。

    这可以通过将 web 服务实例转换为 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 上?虽然没有找到任何东西......
    • 我有一些关于 WS-security (xml-object) 的基本结构的代码,我将在明天查找。但是数据加密(base64编码)不是其中的一部分,所以你必须自己做。
    • 我发布了有关 WS-Security 标头的 Delphi 代码。请注意,有两个版本(至少我知道)- 2003.06 和 2004.01。两者都添加在要点中:gist.github.com/ronaldhoek/ff7611a0b4bd03c01f72c3dd5a4f0a5c
    • 另外关于编码,Delphi 有一个称为“System.NetEncoding”的单元(启动 Delphi 10 左右),这将有助于编码/解码数据。
    • 非常感谢。当我有空的时候,我会看一下 Delphi 中的 WS-security。看起来很有希望。与此同时,我决定开发一个 Delphi 可以使用的 .NET Framework DLL。
    【解决方案2】:

    .NET Framework 完全支持 SOAP 服务。我用 C# 开发了一个 .NET Framework 应用程序,并构建了一个可供 Delphi、.NET Core 等使用的 DLL。这是一个有点迂回的解决方案,但我能找到最简单的解决方案。

    在 C# 中访问服务:https://docs.microsoft.com/en-us/dotnet/framework/wcf/accessing-services-using-a-wcf-client

    导出 DLL 函数:Is is possible to export functions from a C# DLL like in VS C++?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-15
      • 1970-01-01
      • 2010-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多