3

I have integrated my web site with TFIM for SSO. SSO is working fine but i am unable to get the Signature in SAMLResponse. it's getting null. but it is already there in SAMLResponse. When am trying to get the signature value from samlresponse it giving me nullpointerexception

package com.saml;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.opensaml.Configuration;
import org.opensaml.DefaultBootstrap;
import org.opensaml.saml2.core.Response;
import org.opensaml.saml2.core.Subject;
import org.opensaml.security.SAMLSignatureProfileValidator;
import org.opensaml.xml.ConfigurationException;
import org.opensaml.xml.XMLObject;
import org.opensaml.xml.io.Unmarshaller;
import org.opensaml.xml.io.UnmarshallerFactory;
import org.opensaml.xml.io.UnmarshallingException;
import org.opensaml.xml.security.credential.Credential;
import org.opensaml.xml.security.x509.BasicX509Credential;
import org.opensaml.xml.signature.SignatureValidator;
import org.apache.commons.codec.binary.Base64;
import org.opensaml.xml.validation.ValidationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

public class ReceiveSAMLResponse {

    public String receiveSAMLResponse(HttpServletRequest request)
            throws ParserConfigurationException, SAXException, IOException,
            UnmarshallingException, ValidationException, CertificateException {
        /* Getting the response string from HTTP Request object */
        String responseString = (String) request.getParameter("SAMLResponse");

        /* Decoding Base64 response string to get the XML string */

        String responseXml = new String(Base64.decodeBase64(responseString
                .getBytes()));

        System.out.println(responseXml);
        /* Generating SAML Response object from XML string */
        try {
            DefaultBootstrap.bootstrap();
        } catch (ConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
                .newInstance();
        documentBuilderFactory.setNamespaceAware(true);
        DocumentBuilder docBuilder = documentBuilderFactory
                .newDocumentBuilder();
        ByteArrayInputStream is = new ByteArrayInputStream(
                responseXml.getBytes());
        Document document = docBuilder.parse(is);
        Element element = document.getDocumentElement();

        UnmarshallerFactory unmarshallerFactory = Configuration
                .getUnmarshallerFactory();

        Unmarshaller unmarshaller = unmarshallerFactory
                .getUnmarshaller(element);

        XMLObject xmlObj = unmarshaller.unmarshall(element);
        Response response = (Response) xmlObj;

        /* Validating the signature on the response */
        // validateSignature(response);

        /* If validation was successful, get the username from the response. */
        Subject subject = response.getAssertions().get(0).getSubject();
        String username = subject.getNameID().getValue();
        return username;
    }

    private void validateSignature(Response response)
            throws ValidationException, FileNotFoundException,
            CertificateException {
        SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator();
        try {
            profileValidator.validate(response.getSignature());
        } catch (ValidationException e) {
            /* Indicates signature did not conform to SAML Signature profile */
            e.printStackTrace();
            throw e;
        }

        Credential verificationCredential = getVerificationCredential();
        SignatureValidator sigValidator = new SignatureValidator(
                verificationCredential);
        try {
            sigValidator.validate(response.getSignature());
        } catch (ValidationException e) {

            e.printStackTrace();
            throw e;
        }
    }

    private Credential getVerificationCredential()
            throws FileNotFoundException, CertificateException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
                "/pathToYourCertificte"));
        CertificateFactory cf = CertificateFactory.getInstance("X509");
        X509Certificate cert = (X509Certificate) cf.generateCertificate(bis);
        BasicX509Credential x509Credential = new BasicX509Credential();
        x509Credential.setPublicKey(cert.getPublicKey());
        x509Credential.setEntityCertificate(cert);
        Credential credential = x509Credential;
        return credential;
    }

}

....................................

saml response in xml file

<samlp:Response xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Destination="https://10.44.90.29:8443/SAMLShareFile/saml/samlresponse" ID="FIMRSP_604af2be-0150-1ff0-adad-8154af08b58c" InResponseTo="-5346144739450824145" IssueInstant="2015-10-13T08:22:15Z" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://10.44.189.168:444/apjct/sps/NewRelic/saml20</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"></samlp:StatusCode></samlp:Status><saml:Assertion ID="Assertion-uuid604af281-0150-1512-8c38-8154af08b58c" IssueInstant="2015-10-13T08:22:15Z" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://10.44.189.168:444/apjct/sps/NewRelic/saml20</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="uuid604af289-0150-1dab-a25e-8154af08b58c"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod><ds:Reference URI="#Assertion-uuid604af281-0150-1512-8c38-8154af08b58c"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><xc14n:InclusiveNamespaces xmlns:xc14n="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="xs saml xsi"></xc14n:InclusiveNamespaces></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod><ds:DigestValue>pMf0E/z1rS9OkTOLc+0aoD7cl30=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>SW9BaJm0rGJAOG62Il1v46YsqocHXNpmcQKAmSIKDX4tRN3EbUHeqFcVfJmmUGDe4uC1H115SOCehQAkJ35lLBnVsda2WHgu4kWdGC8j+kaw0y9zjzngrHZljBpzU2h87zk4X+fGXvtCmBUH7xfrID4tQ6ODdhoWjd6K8s21S50=</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICBzCCAXCgAwIBAgIEQH26vjANBgkqhkiG9w0BAQQFADBIMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGVGl2b2xpMQ4wDAYDVQQLEwVUQU1lQjEYMBYGA1UEAxMPZmltZGVtby5pYm0uY29tMB4XDTA0MDQxNDIyMjcxMFoXDTE3MTIyMjIyMjcxMFowSDELMAkGA1UEBhMCVVMxDzANBgNVBAoTBlRpdm9saTEOMAwGA1UECxMFVEFNZUIxGDAWBgNVBAMTD2ZpbWRlbW8uaWJtLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAiZ0D1X6rk8+ZwNBTVZt7C85m421a8A52Ksjw40t+jNvbLYDp/W66AMMYD7rB5qgniZ5K1p9W8ivM9WbPxc2u/60tFPg0e/Q/r/fxegW1K1umnay+5MaUvN3p4XUCRrfg79OvurvXQ7GZa1/wOp5vBIdXzg6i9CVAqL29JGi6GYUCAwEAATANBgkqhkiG9w0BAQQFAAOBgQBXiAhxm91I4m+g3YX+dyGc352TSKO8HvAIBkHHFFwIkzhNgO+zLhxg5UMkOg12X9ucW7leZ1IB0Z6+JXBrXIWmU3UPum+QxmlaE0OG9zhp9LEfzsE5+ff+7XpS0wpJklY6c+cqHj4aTGfOhSE6u7BLdI26cZNdzxdhikBMZPgdyQ==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><saml:Subject><saml:NameID Format="urn:ibm:names:ITFIM:5.1:accessmanager">musaddique</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="-5346144739450824145" NotOnOrAfter="2015-10-13T08:32:15Z" Recipient="https://10.44.90.29:8443/SAMLShareFile/saml/samlresponse"></saml:SubjectConfirmationData></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2015-10-13T08:12:15Z" NotOnOrAfter="2015-10-13T08:32:15Z"><saml:AudienceRestriction><saml:Audience>musaddique</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant="2015-10-13T08:22:15Z" SessionIndex="uuid604af260-0150-14b6-8127-8154af08b58c" SessionNotOnOrAfter="2015-10-13T09:22:15Z"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement><saml:AttributeStatement><saml:Attribute Name="AuthenticatingAuthority" NameFormat="urn:oasis:names:tc:SAML:2.0:assertion"><saml:AttributeValue xsi:type="xs:string">musaddique</saml:AttributeValue></saml:Attribute></saml:AttributeStatement></saml:Assertion></samlp:Response>
Musaddique S
  • 1,539
  • 2
  • 15
  • 36

2 Answers2

4

Your SAML has only assertion part () being signed, so you should get signature from assertion object not response object: try response.getAssertions().get(0).getSignature(). Base on SAML 2.0 specification, SAML response has to be signed, but not both response and sssertion are mandatory.

Michael.G
  • 41
  • 2
0

I wrote this code in my SamlProvider. I didn't used it because the Idp was not requesting the HTTPS protocol and certificates in saml so it's not a "certified solution" I load the certificate from a file so you migth directly inject your BufferedInputStream.

private Credential getCredential() {
        BasicX509Credential credential = null;
        try {
            // read private key
            File privateKeyFile = new File(derFile);
            FileInputStream inputStreamPrivateKey = new FileInputStream(privateKeyFile);
            byte[] encodedPrivateKey = new byte[(int) privateKeyFile.length()];
            inputStreamPrivateKey.read(encodedPrivateKey);
            inputStreamPrivateKey.close();
            PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
            RSAPrivateKey privateKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(
                    privateKeySpec);
            // read the certificate
            InputStream inStream = new FileInputStream(pemFile);
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            X509Certificate cert = (X509Certificate) cf.generateCertificate(inStream);
            // create credential
            credential = new BasicX509Credential();
            credential.setEntityCertificate((java.security.cert.X509Certificate) cert);
            credential.setPrivateKey(privateKey);
        } catch (Exception e) {
            Logger.error("failed getting credential!", e);
        }
        return credential;
    }

Hope it helps.

Yuri Blanc
  • 636
  • 10
  • 24