WSSE signature plugin for SecurityTokenReference
jaspercram opened this issue · 0 comments
jaspercram commented
I need to connect to a SOAP server that utilizes a WSSE authentication method different from the one available in Zeep. Unfortunately, I lack the knowledge and time to create a pull request for this plugin . However, I will share the code here in case it is useful to someone else. I apologize for not being able to provide more detailed information on how to use this plugin. Please feel free to ignore it or close this issue if necessary.
class SignaturePlugin(zeep.Plugin):
def egress(self, envelope, http_headers, operation, binding_options):
# Insert filename here
key = xmlsec.Key.from_file(XXXXXXX, xmlsec.constants.KeyDataFormatPem)
soap_env = zeep.utils.detect_soap_env(envelope)
# Create the Signature node.
signature = xmlsec.template.create(envelope, xmlsec.Transform.EXCL_C14N, xmlsec.Transform.RSA_SHA256)
# Insert the Signature node in the wsse:Security header.
security = get_security_header(envelope)
security.insert(0, signature)
# Perform the actual signing.
ctx = xmlsec.SignatureContext()
ctx.key = key
_sign_node(ctx, signature, envelope.find(QName(soap_env, 'Body')))
timestamp = security.find(QName(zeep.ns.WSU, 'Timestamp'))
if timestamp is not None:
_sign_node(ctx, signature, timestamp)
ctx.sign(signature)
# Place the X509 data inside a WSSE SecurityTokenReference within
# KeyInfo. The recipient expects this structure, but we can't rearrange
# like this until after signing, because otherwise xmlsec won't populate
# the X509 data (because it doesn't understand WSSE).
key_info = xmlsec.template.ensure_key_info(signature)
sec_token_ref = etree.SubElement(key_info, QName(zeep.ns.WSSE, 'SecurityTokenReference'))
# Create the KeyIdentifier node.
key_identifier = etree.SubElement(
sec_token_ref,
etree.QName(zeep.ns.WSSE, 'KeyIdentifier'),
EncodingType='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary',
ValueType='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier',
)
# Insert Key Identifier here
key_identifier.text = 'XXXXXXX'
sec_token_ref.append(key_identifier)
return envelope, http_headers