我有 XML 文档:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<saml2p:ArtifactResolve xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Version="2.0"
IssueInstant="2020-06-01T10:25:15+02:00">
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">TEST</saml2:Issuer>
<saml2p:Artifact>AAQAAKFbFR94fxqmioAqjJUwfHTFVHTDBTVHdBwwTW+ehcM19zsk=</saml2p:Artifact>
</saml2p:ArtifactResolve>
</soapenv:Body>
</soapenv:Envelope>
我尝试以这种方式执行此操作:
$results = array();
$filename = 'cert.p12';
$password = 'certpass';
$priv_key = openssl_pkcs12_read(file_get_contents($filename), $results, $password);
$doc = new DOMDocument();
$doc->loadXML($xml);
$xp = new DOMXPath($doc);
$xp->registerNamespace('soapenv', 'http://schemas.xmlsoap.org/soap/envelope/');
$xp->registerNamespace('saml2p','urn:oasis:names:tc:SAML:2.0:protocol');
$xp->registerNamespace('saml2','urn:oasis:names:tc:SAML:2.0:assertion');
$xp->registerNamespace('ds',XMLSecurityDSig::XMLDSIGNS);
$artifactResolveNode = $xp->query('/*[local-name()=\'Envelope\']/*[local-name()=\'Body\']/*[local-name()=\'ArtifactResolve\']')->item(0);
if($artifactResolveNode){
$objDSig = new XMLSecurityDSig();
$objDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N);
$objDSig->addReference(
$artifactResolveNode,
XMLSecurityDSig::SHA256,
array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', 'http://www.w3.org/2001/10/xml-exc-c14n#'),
array('force_uri' => true)
);
$objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA256, array('type' => 'private'));
$objKey->loadKey($results['pkey'], FALSE);
$objDSig->sign($objKey);
$objDSig->add509Cert($results['cert']);
$objDSig->appendSignature($doc->documentElement());
echo $doc->saveXML();
}
我想将 Signature 节点放在 ISSUER 和 ARTIFACT 之间。此位置对于正确发送 SOAP 信封非常重要。有可能的?
呼啦一阵风