¿Cómo se analiza el elemento Firma de una respuesta SAML usando xmlcrypto?
-
21-12-2019 - |
Pregunta
estoy tratando de usar xmlcripto analizar y validar el <ds:Signature>
elemento de una respuesta SAML.La respuesta fue recibida de mi SSOCírculo Pruebe el proveedor de identidad (consulte a continuación la respuesta SAML completa) y parece ser un estándar samlp
respuesta que contiene una Aserción que ha sido firmada correctamente usando una firma digital xml.
Aquí está el código que estoy usando.Esto se ha tomado de la ayuda de xmlcrypto en github.
CaféScript
validateSignature: (saml) ->
doc = new @xmldom.DOMParser().parseFromString saml
signature = @xmlCrypto.xpath(doc, "/*/*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']")[0]
signed = new @xmlCrypto.SignedXml null, idAttribute: 'AssertionID'
signed.loadSignature signature.toString() # this line fails as signature is undefined
Como puede ver, el código anterior utiliza el xmlCrypto.xpath()
función para recuperar el <ds:Signature>
elemento del documento xml analizado, sin embargo, el resultado de esta función siempre es undefined
Respuesta SAML
<samlp:Response ID="s208442fc7db110e1a6e9df3f6f1c66ff8cd64219c" InResponseTo="_de666b2c-1b3c-de17-1cde-0d97211b1ddd" Version="2.0" IssueInstant="2014-07-29T14:33:45Z" Destination="https://localhost/security/saml2/response" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://idp.ssocircle.com</saml:Issuer>
<samlp:Status xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
</samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
</samlp:Status>
<saml:Assertion ID="s2b6bb561a07e30465057af94c7aff92f8b0e11143" IssueInstant="2014-07-29T14:33:45Z" Version="2.0" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<saml:Issuer>http://idp.ssocircle.com</saml:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<ds:Reference URI="#s2b6bb561a07e30465057af94c7aff92f8b0e11143">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>Lvm7MFE/Chy3gR97omBDlkNmwO0=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>GUBxQmOF0yWvC [...] YslXU=</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIICjDCCAXSg [...] WjeU5FLwDZR0Q=</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" NameQualifier="http://idp.ssocircle.com">biofractal@gmail.com</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData InResponseTo="_de666b2c-1b3c-de17-1cde-0d97211b1ddd" NotOnOrAfter="2014-07-29T14:43:45Z" Recipient="https://localhost/security/saml2/response" />
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2014-07-29T14:23:45Z" NotOnOrAfter="2014-07-29T14:43:45Z">
<saml:AudienceRestriction>
<saml:Audience>gp-sso-localhost</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2014-07-29T08:47:22Z" SessionIndex="s2cd309df973ca61fd0b359e968208375f65d35b01">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
</saml:Assertion>
</samlp:Response>
Solución
El problema fue con el XPATH, que es específico para SAML que contiene su firma en la raíz.Para encontrar la firma dentro de la afirmación interna, debe usar la siguiente línea, con el XPATH actualizado:
signature = @xmlCrypto.xpath(doc, ".//*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']")[0]