Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WSSE signature plugin for SecurityTokenReference #1419

Open
jaspercram opened this issue May 28, 2024 · 0 comments
Open

WSSE signature plugin for SecurityTokenReference #1419

jaspercram opened this issue May 28, 2024 · 0 comments

Comments

@jaspercram
Copy link

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant