Порядок подписи и метки времени в заголовке SOAP

Я разрабатывал клиент vb.net, который подключается к веб-сервису с использованием SOAP. Этому веб-сервису необходимо, чтобы сообщение SOAP было подписано и имело временную метку.

На данный момент все возможно, используя WSE 2.0 с пакетом обновления 3 (SP3). Я смог подписать сообщение и включить тег безопасности в заголовок SOAP, а также добавить метку времени, как вы можете видеть в этом примере:

Это то что я отправляю

      <soap:Header>
        <wsa:Action>http://www.openuri.org/procesa</wsa:Action>
        <wsa:MessageID>
        uuid:8462973d-f108-4b27-999f-730663978d5b</wsa:MessageID>
        <wsa:ReplyTo>
          <wsa:Address>
          http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous</wsa:Address>
        </wsa:ReplyTo>
        <wsa:To>
        https://serveis-pre.app.aoc.cat/siri-proxy/services/Sincron</wsa:To>
        <wsse:Security soap:mustUnderstand="1">
          <wsu:Timestamp wsu:Id="Timestamp-05bf25bd-3ca0-4c4a-8052-996353dae4ad">
            <wsu:Created>2011-07-20T10:28:56Z</wsu:Created>
            <wsu:Expires>2011-07-20T10:33:56Z</wsu:Expires>
          </wsu:Timestamp>
          <wsse:BinarySecurityToken ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
          EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
          xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
          wsu:Id="SecurityToken-faacda4d-8c09-4c30-9538-30e95daf674e">      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</wsse:BinarySecurityToken>
          <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
            <SignedInfo>
              <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"
              xmlns:ds="http://www.w3.org/2000/09/xmldsig#" />
              <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
              <Reference URI="#Id-3ec311d8-8c01-4806-af7e-282a9ae69be7">
                <Transforms>
                  <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                </Transforms>
                <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                <DigestValue>67QHYb7b816b0zisspMyq54mFBU=</DigestValue>
              </Reference>
            </SignedInfo>
            <SignatureValue> T7iT+m/JPDCtNVlj72Dj4Mofb/lNIWKLmLf52xuk6A5r1bAW+VH+ZYTbyEBzjLCMt37MiCwT+G6eNiTOfTn59Lxrcmw9ZG2U/1i02EqXA7akNoS+wMk1a9zN28yWDX2QOEEihltnFkJkQksQKI0ZK7/BZLlMFDudaujM2yYdkkA=</SignatureValue>
            <KeyInfo>
              <wsse:SecurityTokenReference>
                <wsse:Reference URI="#SecurityToken-faacda4d-8c09-4c30-9538-30e95daf674e"
                ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
              </wsse:SecurityTokenReference>
            </KeyInfo>
          </Signature>
        </wsse:Security>
      </soap:Header>
      <soap:Body wsu:Id="Id-3ec311d8-8c01-4806-af7e-282a9ae69be7">
... THE MESSAGE BODY ....

Проблема заключается в том, что сервер, на котором работает веб-служба, настроен на распознавание сообщения SOAP, в котором тег подписи находится над тегом временной метки, и по умолчанию WSE 2.0 SP3 включает эту информацию в заголовок SOAP в обратном порядке.

Порядок тегов в моем сообщении SOAP:

<soap:Header>
    <wsa:Action>
    <wsa:MessageID>
    <wsa:ReplyTo>
        <wsa:Address>
    </wsa:ReplyTo>
    <wsa:To>
    <wsse:Security>
        <wsu:Timestamp>
            <wsu:Created>
            <wsu:Expires>
        </wsu:Timestamp>
        <wsse:BinarySecurityToken>
        <Signature>
            <SignedInfo>
                <ds:CanonicalizationMethod>
                <SignatureMethod>
                <Reference>
                    <Transforms>
                        <Transform Algorithm/>
                    </Transforms>
                    <DigestMethod>
                    <DigestValue>
                </Reference>
            </SignedInfo>
            <SignatureValue>
            <KeyInfo>
                <wsse:SecurityTokenReference>
            </KeyInfo>
        </Signature>
    </wsse:Security>
</soap:Header>
<soap:Body>

Порядок, в котором сервер ожидает теги:

<soap:Header>
    <wsa:Action>
    <wsa:MessageID>
    <wsa:ReplyTo>
        <wsa:Address>
    </wsa:ReplyTo>
    <wsa:To>
    <wsse:Security>
        <wsse:BinarySecurityToken>
        <Signature>
            <SignedInfo>
                <ds:CanonicalizationMethod>
                <SignatureMethod>
                <Reference>
                    <Transforms>
                        <Transform Algorithm/>
                    </Transforms>
                    <DigestMethod>
                    <DigestValue>
                </Reference>
            </SignedInfo>
            <SignatureValue>
            <KeyInfo>
                <wsse:SecurityTokenReference>
            </KeyInfo>
        </Signature>
        <wsu:Timestamp>
            <wsu:Created>
            <wsu:Expires>
        </wsu:Timestamp>
    </wsse:Security>
</soap:Header>
<soap:Body>

Есть ли способ изменить этот порядок?

Любые предложения о том, как я могу это сделать?

1 ответ

Решение

После некоторого тестирования я нашел способ перехватить создание строки XML, отправленной на сервер.

Чтобы изменить сообщение SOAP XML перед его отправкой на сервер, необходимо переопределить ProcessMessage саб на Microsoft.Web.Services2.WebServicesClientProtocol класс вашего SOAP-клиента.

Сначала вы создаете новый класс, который наследуется от SoapOutputFilter и переопределяет подпрограмму ProcessMessage, выполняя то, что вы хотите.

Public Class YourOutputFilterClass
    Inherits SoapOutputFilter

    Public Overrides Sub ProcessMessage(ByVal envelope As SoapEnvelope)
        'Find the XmlNode you want to change

        'Change the XmlNode
    End Sub

End Class

Затем вы устанавливаете свой новый класс как OutputFilter для вашего Microsoft.Web.Services2.WebServicesClientProtocol Учебный класс:

Dim YourSOAPClient as New SoapClientClass()
Dim YourOutputFilter as New YourOutputFilterClass()

YourSOAPClient.Pipeline.OutputFilters.Insert(0, YourOutputFilter)

Благодаря этому ваш OutputFilter сможет изменить сообщение SOAP до его отправки.

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