I am trying to implement SAML 2.0 by signing a response instead of an assertion. I have 3 existing providers that accept my signature at the approval level, however the new provider requests it at the protocol / response level. I work at Google and debug about 8 hours, and I can’t find a valid example of what I am doing wrong. My code below shows what I'm doing, and the last 10 lines or so are the differences I implemented (in if / else). In addition, I noticed in my XML that my SignatureValue and DigestValue are empty. Can someone point me to some clear documentation or, even better, an example of a working response signature using openSAML? At this point, any help is appreciated.
Assertion assertion = OpenSamlHelper.CreateSamlAssertion( issuer.trim(), recipient.trim(), domain.trim(), subject.trim(), attributes); // // Sign // Credential signingCredential = getSigningCredential(keystore, storetype, storepass, alias, keypass); Signature signature = (Signature) Configuration.getBuilderFactory() .getBuilder(Signature.DEFAULT_ELEMENT_NAME) .buildObject(Signature.DEFAULT_ELEMENT_NAME); signature.setSigningCredential(signingCredential); signature.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1); signature.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); SecurityConfiguration secConfiguration = Configuration.getGlobalSecurityConfiguration(); NamedKeyInfoGeneratorManager namedKeyInfoGeneratorManager = secConfiguration.getKeyInfoGeneratorManager(); KeyInfoGeneratorManager keyInfoGeneratorManager = namedKeyInfoGeneratorManager.getDefaultManager(); KeyInfoGeneratorFactory keyInfoGeneratorFactory = keyInfoGeneratorManager.getFactory(signingCredential); KeyInfoGenerator keyInfoGenerator = keyInfoGeneratorFactory.newInstance(); KeyInfo keyInfo = null; try { keyInfo = keyInfoGenerator.generate(signingCredential); } catch (Exception e) { logger.error(e); } signature.setKeyInfo(keyInfo); String saml = ""; try { MarshallerFactory marshallerFactory = Configuration.getMarshallerFactory(); if (signatureType == SignatureType.Response) { response.setSignature(signature); marshallerFactory.getMarshaller(response).marshall(response); } if (signatureType == SignatureType.Assertion) { assertion.setSignature(signature); marshallerFactory.getMarshaller(assertion).marshall(assertion); } Signer.signObject(signature);
UPDATE: The XML I received with the code above did not include the signatureValue or Digest Value, as shown below.
<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="#_651cc837-e890-46c7-9cf9-646ffd38aaad"> <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#"> <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="xs"/> </ds:Transform> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <ds:DigestValue/> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue/>
After moving Signer.signObject (signature); to the point after joining the answer, I get the following XML ..
<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="#_273e38e9-3b51-4845-8b8b-f0970e3e9bab"> <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#"> <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="xs"/> </ds:Transform> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <ds:DigestValue>UlVtsjSAvtjOLMbw+HUX9n7FtxM=</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue> jM7GxZ77VBHuAatMXLx14s0ExOmmfDpBhCpF8OKV4F3C1BiRutM41aTH25yhgSn+6l4TkK6kEDbFOYI6isvJUhtdVgH4E1xJl0DFfvPJphTF096acvJrLPehpsFd2Ab6sARuV1sbg/gwNFzvlHJWgit5NxHNuFN1qcv3vuhvQ83fOfxxuyLyJrEjpqvbRzwWepHiuTVHlNObrUvjVxEc7AUKPtwTqGlA6y3SdzIDwjN/LsB1V6PWhiMZsbxJx3LUuk5UECOYmRhKQifZWdOdvHoWBq05J54I6RvAplNDTfRBr4AM+tfIz3OXpN6OpKdSC43HRg9LO9bXprui+4CvrQ== </ds:SignatureValue> tfIz3OXpN6OpKdSC43HRg9LO9bXprui + 4CvrQ == <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="#_273e38e9-3b51-4845-8b8b-f0970e3e9bab"> <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#"> <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="xs"/> </ds:Transform> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <ds:DigestValue>UlVtsjSAvtjOLMbw+HUX9n7FtxM=</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue> jM7GxZ77VBHuAatMXLx14s0ExOmmfDpBhCpF8OKV4F3C1BiRutM41aTH25yhgSn+6l4TkK6kEDbFOYI6isvJUhtdVgH4E1xJl0DFfvPJphTF096acvJrLPehpsFd2Ab6sARuV1sbg/gwNFzvlHJWgit5NxHNuFN1qcv3vuhvQ83fOfxxuyLyJrEjpqvbRzwWepHiuTVHlNObrUvjVxEc7AUKPtwTqGlA6y3SdzIDwjN/LsB1V6PWhiMZsbxJx3LUuk5UECOYmRhKQifZWdOdvHoWBq05J54I6RvAplNDTfRBr4AM+tfIz3OXpN6OpKdSC43HRg9LO9bXprui+4CvrQ== </ds:SignatureValue>
Devon source share