pysaml2
pysaml2 copied to clipboard
Help Creating a Subject/SubjectConfirmation/SubjectConfirmationData/KeyInfo/KeyValue/RSAKeyValue Element
We need the SAML Assertion to create the Subject element with the following structure: Subject/SubjectConfirmation/SubjectConfirmationData/KeyInfo/KeyValue/RSAKeyValue element. Otherwise Signature verification fails based on our partner requirements. I have updated the SubjectConfirmationData() element for SCM_HOLDER_OF_KEY. I am unsure though how to have the KeyInfo -> KeyInfoValue -> RSAKeyValue element to populate in this section during signing. I have really tried to figure this out but unsure based on the documentation.
Here is the code in question:
###Create the SAML assertion ###
###the audience should be the url of the server that will receive the SAML assertion
###the role should be the role of the requester of the data, e.g. MedicalDoctor
###the purposeOfUse should be the purpose of use of the data, e.g. TREATMENT, possible values are: https://www.hl7.org/fhir/codesystem-nhin-purposeofuse.html
issuer = ISSUER
not_on_or_after = self.issued_at + timedelta(hours=1)
refID = str(uuid.uuid4())
# Create SAML assertion
issuer = Issuer(name_qualifier=NAMEID_FORMAT_X509SUBJECTNAME, text=CERT_SUBJECT)
subjectConfirmationData = SubjectConfirmationData()
subject = Subject(
name_id=NameID(format=NAMEID_FORMAT_X509SUBJECTNAME, text=CERT_SUBJECT),
subject_confirmation=SubjectConfirmation(
method=SCM_HOLDER_OF_KEY,
subject_confirmation_data=subjectConfirmationData
)
)
# Create the attribute statement
attributes = [
Attribute(
name="urn:oasis:names:tc:xspa:1.0:subject:subject-id",
friendly_name="XSPA Subject",
name_format="urn:oasis:names:tc:SAML:2.0:attrname-format:basic",
attribute_value=AttributeValue("valid")
),
Attribute(
name="urn:oasis:names:tc:xspa:1.0:subject:organization",
friendly_name="XSPA Organization",
name_format="urn:oasis:names:tc:SAML:2.0:attrname-format:uri",
attribute_value=AttributeValue(ORGANIZATION)
),
Attribute(
name="urn:oasis:names:tc:xspa:1.0:subject:organization-id",
friendly_name="XSPA Organization ID",
name_format="urn:oasis:names:tc:SAML:2.0:attrname-format:uri",
attribute_value=AttributeValue(ORGANIZATION_ID)
),
Attribute(
name="urn:ihe:iti:xca:2010:homeCommunityId",
friendly_name="XCA Home Community ID",
name_format="urn:oasis:names:tc:SAML:2.0:attrname-format:uri",
attribute_value=AttributeValue(HOME_COMMUNITY_ID)
),
Attribute(
name="urn:oasis:names:tc:xspa:1.0:subject:purposeofuse",
friendly_name="Purpose of Use",
attribute_value=AttributeValue(purposeOfUse)
),
Attribute(
name="urn:oasis:names:tc:xacml:2.0:subject:role",
friendly_name="HL7 Role",
attribute_value=AttributeValue(role)
)
]
attribute_statement = AttributeStatement(attribute=attributes)
conditions = Conditions(
not_before=self.issued_at.strftime('%Y-%m-%dT%H:%M:%S.%f')[:-3] + 'Z',
not_on_or_after=not_on_or_after.strftime('%Y-%m-%dT%H:%M:%S.%f')[:-3] + 'Z',
audience_restriction=AudienceRestriction([
Audience(audience)
])
)
authn_statement = AuthnStatement(
authn_instant=self.issued_at.strftime('%Y-%m-%dT%H:%M:%S.%f')[:-3] + 'Z',
authn_context=AuthnContext(
authn_context_class_ref=AuthnContextClassRef(
text="urn:oasis:names:tc:SAML:2.0:ac:classes:Password"
)
)
)
assertion = Assertion(
id="_"+refID,
issue_instant=self.issued_at.strftime('%Y-%m-%dT%H:%M:%S.%f')[:-3] + 'Z',
issuer=issuer,
subject=subject,
conditions=conditions,
attribute_statement=attribute_statement,
version="2.0",
authn_statement=authn_statement
)
assertion_string = str(assertion)
assertion_string = assertion_string.replace("Issuer>","Issuer>" + "<ds:Signature xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\" Id=\"placeholder\"></ds:Signature>")
assertion_string = assertion_string.replace("ns0", "samlns")
signed_saml_root = XMLSigner(method=signxml.methods.enveloped, c14n_algorithm="http://www.w3.org/2001/10/xml-exc-c14n#")\
.sign(saml_root, key=self.key, cert=self.cert, always_add_key_value=True)
verified_data = XMLVerifier().verify(signed_saml_root, x509_cert=self.cert).signed_xml
Appreciate if someone could advise on how to do this with