I need to create a soap message that contains something like this:
<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
is of type AnyType
.
I'm almost there with this code:
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
}
}
This is the result:
<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>
The problem is that AssertionType
needs to be wrapped in a seperate Assertion
element and not inside SubjectConfirmationData
.
How can I add this extra element?
Update 1: I also tried something like this, but I get an error:
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
}
This is the error:
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
Update 2:
I also tried this, but then I get a weird result:
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
}
This is the result:
<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>
Update 3:
I solved this by creating the complete header in a custom zeep plugin.
The headers are made with plain lxml and signed with xmlsec