I am not able to generate SAMLResponse, receiving errors; "Unable to compute signature, Signature XMLObject does not have the XMLSignature created during marshalling", "XMLObject does not have an XMLSignature instance, unable to compute signature".
I also tried logging the input stream of the public key by inStream.read(), It prints "inStream: -1", which I believe is returned when the input file is empty, which is definitely not empty, I am confused, is this is the error or what?
Receiving following lines of error logs;
{ role=ADMIN } - Unable to compute signature, Signature XMLObject does not have the XMLSignature created during marshalling
{ role=ADMIN } - XMLObject does not have an XMLSignature instance, unable to compute signature
{ role=ADMIN } - XMLObject does not have an XMLSignature instance, unable to compute signature
{ role=ADMIN } - org.opensaml.xml.signature.SignatureException: XMLObject does not have an XMLSignature instance, unable to compute signature
{ role=ADMIN } - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException: null // at the mentioned error point
Code:
package HIE.utils;
public class SSOSAMLResponse1 {
public Response createSAMLResponse(final String subjectId, final HashMap<String, List<String>> attributes, String issuer) {
try {
DefaultBootstrap.bootstrap();
DateTime datetime = new DateTime(Utilities.getCurrentTimeStamp());
Issuer responseIssuer = null;
Issuer assertionIssuer = null;
Subject subject = null;
AttributeStatement attributeStatement = null;
Status status = createStatus();
if (!Utilities.isNull(issuer)) {
responseIssuer = createIssuer(issuer);
assertionIssuer = createIssuer(issuer);
}
if (!Utilities.isNull(subjectId)) {
subject = createSubject(subjectId);
}
if (!Utilities.isNull(attributes) && attributes.size() != 0) {
attributeStatement = createAttributeStatement(attributes);
}
Conditions conditions = createConditions(datetime);
AuthnStatement authnStatement = createAuthnStatement(datetime);
Assertion assertion = createAssertion(datetime, subject, assertionIssuer, authnStatement, attributeStatement, conditions);
Signature signature = createSignature();
assertion.setSignature(signature);
Signer.signObject(signature); // point of error
return createResponse(datetime, responseIssuer, status, assertion);
} catch(Throwable t) {
log.warn(t.getMessage());
log.warn(t.getLocalizedMessage());
log.warn(t.toString());
t.printStackTrace();
return null;
}
}
// skipping other defined functions
private Signature createSignature() throws Throwable {
String absolutePath = "C:/Users/USER/Desktop/office-projects/medicalservice/src/main/resources/sso/";
String privateKeyLocation = absolutePath + "x509_priv.pem";
String publicKeyLocation = absolutePath + "x509_cert.crt";
SignatureBuilder builder = new SignatureBuilder();
Signature signature = builder.buildObject();
Credential credential = getSigningCredential(publicKeyLocation, privateKeyLocation);
signature.setSigningCredential(credential);
signature.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1);
signature.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
return signature;
}
public Credential getSigningCredential(String publicKeyLocation, String privateKeyLocation) throws Throwable {
// create public key (cert) portion of credential
InputStream inStream = new FileInputStream(publicKeyLocation);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate x509Certificate = (X509Certificate) cf.generateCertificate(inStream);
log.info("inStream: {}", inStream.read());
inStream.close();
// create private key
File file = new File(privateKeyLocation);
String key = new String(Files.readAllBytes(file.toPath()), Charset.defaultCharset());
String privateKeyPEM = key
.replace("-----BEGIN RSA PRIVATE KEY-----", "")
.replaceAll(System.lineSeparator(), "")
.replace("-----END RSA PRIVATE KEY-----", "");
log.info("privateKeyPEM {}", privateKeyPEM);
byte[] encoded = Base64.decodeBase64(privateKeyPEM);
PKCS8EncodedKeySpec kSpec = new PKCS8EncodedKeySpec(encoded);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privateKey = kf.generatePrivate(kSpec);
// create credential and initialize
BasicX509Credential credential = new BasicX509Credential();
credential.setEntityCertificate(x509Certificate);
credential.setPrivateKey(privateKey);
return credential;
}
}
just add these lines after creating Signature, createSignature();