Class: Wssec::Signer
- Inherits:
-
Object
- Object
- Wssec::Signer
- Defined in:
- lib/wssec/signer.rb
Overview
Signs a SOAP envelope with an OASIS WS-Security header carrying a detached XML-DSig signature (RSA-SHA256 / SHA256, exclusive-C14N) over the Body and a Timestamp, exactly as a WSS4J-based gateway expects.
doc = Nokogiri::XML(soap_envelope)
Wssec::Signer.new(
key: rsa_key, cert: x509_cert, key_identifier: "my-key",
inclusive_prefixes: %w[wsse wsu soapenv ds]
).sign!(doc, body_id: "Id-#{SecureRandom.hex(16)}")
doc.to_xml
The signer is vendor-agnostic: key/cert, the token identifier and the C14N
inclusive prefix list are supplied per call, while namespaces, algorithm
identifiers, token types and the timestamp TTL come from config (defaults
to the global Wssec.configuration).
Instance Method Summary collapse
-
#initialize(key:, cert:, key_identifier:, inclusive_prefixes:, timestamp_ttl: nil, config: Wssec.configuration) ⇒ Signer
constructor
key -- OpenSSL::PKey::RSA private key used to sign.
-
#sign!(document, body_id:, now: Time.now.utc) ⇒ Object
Adds the signed wsse:Security header to
document(a Nokogiri doc) in place.
Constructor Details
#initialize(key:, cert:, key_identifier:, inclusive_prefixes:, timestamp_ttl: nil, config: Wssec.configuration) ⇒ Signer
key -- OpenSSL::PKey::RSA private key used to sign. cert -- OpenSSL::X509::Certificate embedded as the BinarySecurityToken. key_identifier -- names the token (BST wsu:Id becomes "X509-#key_identifier"). inclusive_prefixes -- namespace prefixes rendered into each signed subtree (the exclusive-C14N PrefixList); gateway-specific, so the caller supplies it. timestamp_ttl -- seconds until the wsu:Timestamp expires (defaults to config). config -- Wssec::Configuration for namespaces/algorithms/token types.
29 30 31 32 33 34 35 36 |
# File 'lib/wssec/signer.rb', line 29 def initialize(key:, cert:, key_identifier:, inclusive_prefixes:, timestamp_ttl: nil, config: Wssec.configuration) @key = key @cert = cert @key_identifier = key_identifier @inclusive_prefixes = inclusive_prefixes @config = config @timestamp_ttl = || config. end |
Instance Method Details
#sign!(document, body_id:, now: Time.now.utc) ⇒ Object
Adds the signed wsse:Security header to document (a Nokogiri doc) in place.
39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/wssec/signer.rb', line 39 def sign!(document, body_id:, now: Time.now.utc) root = document.root header = root.at_xpath("soapenv:Header", "soapenv" => ns[:soapenv]) || root.prepend_child(Nokogiri::XML::Node.new("soapenv:Header", document)) body = root.at_xpath("soapenv:Body", "soapenv" => ns[:soapenv]) raise Wssec::Error, "envelope has no soapenv:Body" unless body tag_body(body, body_id) security = build_security_header(document, header, now) append_binary_security_token(document, security) append_signature(document, security, body, body_id) document end |