Создайте SOAP-сообщение со сложным типом внутри AnyType, используя Python Zeep - PullRequest
0 голосов
/ 31 декабря 2018

Мне нужно создать мыльное сообщение, которое содержит что-то вроде этого:

<saml:Subject>     
    <saml:SubjectConfirmation>      
      <saml:ConfirmationMethod>
               urn:oasis:names:tc:SAML:1.0:cm:holder-of-key
      </saml:ConfirmationMethod>
      <saml:SubjectConfirmationData>
         <saml:Assertion AssertionID="123" 
                         IssueInstant="2018-12-27T17:59:36.284Z" 
                         Issuer="issuer" 
                         MajorVersion="1" 
                         MinorVersion="1">
            ...
         </saml:Assertion>
      </saml:SubjectConfirmationData>
   </saml:SubjectConfirmation>
</saml:Subject>

SubjectConfirmationData имеет тип AnyType.
Я почти там с этим кодом:

assertion_type = client.get_type("saml:AssertionType")
assertion = assertion_type(
    AssertionID = "123",
    MajorVersion = 1,
    MinorVersion = 1,
    Issuer = "issuer",
    IssueInstant = datetime.now())

subject_confirm = {
    'ConfirmationMethod': 'urn:oasis:names:tc:SAML:1.0:cm:holder-of-key',
    'SubjectConfirmationData': assertion
}

result = {
    'Subject': {
        'SubjectConfirmation': subject_confirm
    }
}

Это результат:

<saml:Subject>
  <saml:SubjectConfirmation>
    <saml:ConfirmationMethod>
          urn:oasis:names:tc:SAML:1.0:cm:holder-of-key
    </saml:ConfirmationMethod>
    <saml:SubjectConfirmationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        MajorVersion="1" 
        MinorVersion="1" 
        AssertionID="123" 
        Issuer="issuer" 
        IssueInstant="2018-12-31T13:10:00.471365"
        xsi:type="saml:AssertionType"/>
  </saml:SubjectConfirmation>
</saml:Subject>

Проблема в том, что AssertionType должен быть заключен в отдельный элемент Assertion, а не внутри SubjectConfirmationData.Как я могу добавить этот дополнительный элемент?

Обновление 1 : Я тоже пробовал что-то подобное, но получаю ошибку:

assertion_elem = client.get_element("saml:Assertion")
assertion = assertion_elem(
    AssertionID = "",
    MajorVersion = 1,
    MinorVersion = 1,
    Issuer = cert_subject,
    IssueInstant = datetime.now())

subj_conf_data_type = client.get_element("saml:SubjectConfirmationData")
subj_conf_data = xsd.AnyObject(assertion_elem, assertion)

subject_confirm = {
    'ConfirmationMethod': 'urn:oasis:names:tc:SAML:1.0:cm:holder-of-key',
    'SubjectConfirmationData': subj_conf_data,
    "KeyInfo": key_info
}

Это ошибка:

  File "...lib\site-packages\zeep\xsd\types\any.py", line 26, in render
    value.xsd_type.render(parent, value.value, None, render_path)
TypeError: render() takes from 3 to 4 positional arguments but 5 were given

Обновление 2 :

Я тоже пробовал это, но потом получаю странный результат:

assertion_elem = client.get_element("saml:Assertion")
assertion = assertion_elem(
    AssertionID = "",
    MajorVersion = 1,
    MinorVersion = 1,
    Issuer = cert_subject,
    IssueInstant = datetime.now())

subject_confirm = {
    'ConfirmationMethod': 'urn:oasis:names:tc:SAML:1.0:cm:holder-of-key',
    'SubjectConfirmationData': {
        'Assertion': assertion
    },
    "KeyInfo": key_info
}

Это результат:

<saml:Subject>
          <saml:SubjectConfirmation>
            <saml:ConfirmationMethod>
                urn:oasis:names:tc:SAML:1.0:cm:holder-of-key
            </saml:ConfirmationMethod>
            <saml:SubjectConfirmationData>{'Assertion': {
    'Conditions': None,
    'Advice': None,
    '_value_1': {
},
    'Signature': None,
    'MajorVersion': 1,
    'MinorVersion': 1,
    'AssertionID': '123',
    'Issuer': 'issuer',
    'IssueInstant': datetime.datetime(2018, 12, 31, 15, 2, 8, 518253)
}}</saml:SubjectConfirmationData>
          </saml:SubjectConfirmation>
        </saml:Subject>

Обновление 3:

Я решил эту проблему, создав полный заголовок в пользовательском плагине Zeep.
Заголовки сделаны с простым lxml иподписано xmlsec

...