How to validate SAML assertion signatures

放肆的年华 提交于 2019-12-24 21:44:05

问题


How to validate SAML assertion signatures?

    for (Assertion assertion : samlResponse.getAssertions()) {
        try {
            if (assertion.getSignature() != null) {
                Optional<X509Certificate> x509Certificate = assertion.getSignature().getKeyInfo().getX509Datas()
                        .stream()
                        .findFirst()
                        .map(x509Data -> x509Data.getX509Certificates()
                                .stream()
                                .findFirst()
                                .orElse(null)
                        );
                if (x509Certificate.isPresent()) {
                    BasicX509Credential credential = new BasicX509Credential();
                    credential.setEntityCertificate(KeyInfoHelper.getCertificate(x509Certificate.get()));
                    // what pub key credential to use here?
                    SignatureValidator validator = new SignatureValidator(credential);
                    validator.validate(assertion.getSignature());
                }
            }
        } catch (ValidationException | CertificateException e) {
            throw new SAMLException(e.getMessage(), e);
        }
    }

Basically what to put in new SignatureValidator(credential)

As far as I understand, A SAML assertion with KeyInfo supplied and a X809 cert should at least validate (SAML: Why is the certificate within the Signature?)

I also have an x509 cert from the idps metadata which I guess should general be used if there is no x509 cert in the assertion or within a trust chain (?)

Basically neither the x509 cert in the assertion nor the cert from the idp metadata seems to work. What am I missing here?


回答1:


Turned out I did everything correctly.

When printing an opensaml object xml you should NOT use the following code:

public static String xmlObjectToString(XMLObject xmlObject) {
    try {
        Marshaller marshaller = Configuration.getMarshallerFactory().getMarshaller(xmlObject);
        StringWriter sw = new StringWriter();
        Element authDOM = marshaller.marshall(xmlObject);
        toString(sw, authDOM);
        return sw.toString();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}


private static void toString(StringWriter rspWrt, Element authDOM) throws ParserConfigurationException, TransformerException {
    DOMSource domSource = new DOMSource(authDOM);
    StreamResult result = new StreamResult(rspWrt);
    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer transformer = tf.newTransformer();
    transformer.transform(domSource, result);
} 

The above code changes some internal states of the original object

Instead go for

org.opensaml.xml.util.XMLHelper.prettyPrintXML(message.getDOM())


来源:https://stackoverflow.com/questions/49263336/how-to-validate-saml-assertion-signatures

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!