Wednesday, May 14, 2014

Exception: "Apache xmlsec IdResolver could not resolve the Element for id reference" while decrypting

org.opensaml.xml.validation.ValidationException: Apache xmlsec IdResolver could not resolve the Element for id reference:

This is an example of a common exception that can be thrown when verifying a signature after decryption an object.

To avoid this, it is often enough to configure your Decryptor using the following setting before decrypting.

decrypter.setRootInNewDocument(true);

16 comments:

  1. Thanks this helped me fix my problem decrypting. I'm now getting the same error while trying to validate a signature only. Any idea how to solve that?

    for example:
    SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator();
    profileValidator.validate( object.getSignature() );
    SignatureValidator sigValidator = new SignatureValidator( validatingCredential );
    sigValidator.validate( object.getSignature() );

    ReplyDelete
  2. Using OpenSAML 3.3.0 api from Shibboleth I am getting the same error: org.opensaml.xmlsec.signature.support.SignatureException: Apache xmlsec IdResolver could not resolve the Element for id.
    Any one can help?

    ReplyDelete
    Replies
    1. Sorry, I dont have any specific advice for this?

      Delete
    2. The IdP is using SHA1 algorithm here. The same code works fine with SHA2 (SHA256). Is this someway related with SHA1 ?

      Delete
    3. Could you post some workable code showing the problem on gist and I will investigate it.

      Delete
    4. This comment has been removed by the author.

      Delete
    5. Hi,
      Here is the java code:
      SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator();
      profileValidator.validate(assertion.getSignature());
      SignatureValidator.validate(assertion.getSignature(), idpMetadata.getCredential());

      I am getting the exception on profile validator. If I ignore that then I am getting another exception on validation.

      For your investigation I am giving you the saml response also:

      https://dl.dropboxusercontent.com/u/55676948/SamlResponse.xml

      Delete
    6. Hi, I have the same Problem. This is basically the example from the Book (A Guide to OpenSAML V3) on page 54. When I call profileValidator.validate(assertion.getSignature()) it throws the aforementioned signature exception.

      Delete
    7. Do you get it when running the example in the book?

      Delete
    8. I found a workaround. I guess the problem starts from SOAP decoding ArtifactResponse. When I marshall the ArtifactResponse, convert it to string and from string reconstruct ArtifactResponse by unmarshal then ProfileValidator works fine. But now I am getting another signature verification error on validating the byte. The error seems to be in the actual byte comparison for the RSA-SHA256 algorithm. It may cause by marshall-unmarshalling, not so sure. Using following code to retrieve SOAP response: AbstractPipelineHttpSOAPClient soapClient = new AbstractPipelineHttpSOAPClient() {
      protected HttpClientMessagePipeline newPipeline() throws SOAPException {
      HttpClientRequestSOAP11Encoder encoder = new HttpClientRequestSOAP11Encoder();
      HttpClientResponseSOAP11Decoder decoder = new HttpClientResponseSOAP11Decoder();
      BasicHttpClientMessagePipeline pipeline = new BasicHttpClientMessagePipeline(
      encoder,
      decoder
      );
      pipeline.setOutboundPayloadHandler(new SAMLOutboundProtocolMessageSigningHandler());
      return pipeline;
      }};

      Delete
    9. @Stefan Rasmusson: The example on the book works fine.

      Delete
  3. This comment has been removed by the author.

    ReplyDelete
  4. In my case it is a SAML response received from the IdP via POST binding. It contains a signed Assertion (not encrypted). I can decode it, print it, everything works fine but when I use the following snippet, it throws the exception:

    if (assertion.isSigned()) {
    SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator();
    profileValidator.validate(assertion.getSignature());
    }

    Is there something specific needed before you can validate the assertion signature?

    ReplyDelete
  5. Hm, the Exception says "Apache xmlsec IdResolver could not resolve the Element for id reference: <...>", and this is exactly the ID of the Assertion. So for some reason, during signature validation, the library cannot find the Assertion in the document and I cannot use the decrypter.setRoot[..] because I'm not trying to decrypt assertion.

    ReplyDelete
  6. HA! I've got it. For some reason, you need to explicitly specify the ID attribute of the assertion before signature validation.

    assertion.getDOM().setIdAttribute("ID", true);

    Without it, apparently the code does not know how to find the referenced object. :-/

    BTW, in the book, on page 54 you have an example like:

    SingatureValidator sigValidator = new SignatureValidator(credential);

    This doesn't work in OpenSAML 3, sice the SignatureValidator has a protected constructor. It should be something like:

    SignatureValidator.validate(assertion.getSignature(), credential);

    ReplyDelete
  7. Great. It works like charm. Thanks for your help

    ReplyDelete