public void signAssertion(Document samlDocument) throws ProcessingException {
    Element originalAssertionElement =
        org.keycloak.saml.common.util.DocumentUtil.getChildElement(
            samlDocument.getDocumentElement(),
            new QName(
                JBossSAMLURIConstants.ASSERTION_NSURI.get(), JBossSAMLConstants.ASSERTION.get()));
    if (originalAssertionElement == null) return;
    Node clonedAssertionElement = originalAssertionElement.cloneNode(true);
    Document temporaryDocument;

    try {
      temporaryDocument = org.keycloak.saml.common.util.DocumentUtil.createDocument();
    } catch (ConfigurationException e) {
      throw new ProcessingException(e);
    }

    temporaryDocument.adoptNode(clonedAssertionElement);
    temporaryDocument.appendChild(clonedAssertionElement);

    signDocument(temporaryDocument);

    samlDocument.adoptNode(clonedAssertionElement);

    Element parentNode = (Element) originalAssertionElement.getParentNode();

    parentNode.replaceChild(clonedAssertionElement, originalAssertionElement);
  }
  /**
   * Sign a node in a document
   *
   * @param doc
   * @param nodeToBeSigned
   * @param keyPair
   * @param publicKey
   * @param digestMethod
   * @param signatureMethod
   * @param referenceURI
   * @return
   * @throws ParserConfigurationException
   * @throws XMLSignatureException
   * @throws MarshalException
   * @throws GeneralSecurityException
   */
  public static Document sign(
      Document doc,
      Node nodeToBeSigned,
      KeyPair keyPair,
      String digestMethod,
      String signatureMethod,
      String referenceURI,
      X509Certificate x509Certificate)
      throws ParserConfigurationException, GeneralSecurityException, MarshalException,
          XMLSignatureException {
    if (nodeToBeSigned == null) throw logger.nullArgumentError("Node to be signed");

    if (logger.isTraceEnabled()) {
      logger.trace("Document to be signed=" + DocumentUtil.asString(doc));
    }

    Node parentNode = nodeToBeSigned.getParentNode();

    // Let us create a new Document
    Document newDoc = DocumentUtil.createDocument();
    // Import the node
    Node signingNode = newDoc.importNode(nodeToBeSigned, true);
    newDoc.appendChild(signingNode);

    if (!referenceURI.isEmpty()) {
      propagateIDAttributeSetup(nodeToBeSigned, newDoc.getDocumentElement());
    }
    newDoc = sign(newDoc, keyPair, digestMethod, signatureMethod, referenceURI, x509Certificate);

    // if the signed element is a SAMLv2.0 assertion we need to move the signature element to the
    // position
    // specified in the schema (before the assertion subject element).
    if (nodeToBeSigned.getLocalName().equals("Assertion")
        && WSTrustConstants.SAML2_ASSERTION_NS.equals(nodeToBeSigned.getNamespaceURI())) {
      Node signatureNode =
          DocumentUtil.getElement(newDoc, new QName(WSTrustConstants.DSIG_NS, "Signature"));
      Node subjectNode =
          DocumentUtil.getElement(
              newDoc, new QName(WSTrustConstants.SAML2_ASSERTION_NS, "Subject"));
      if (signatureNode != null && subjectNode != null) {
        newDoc.getDocumentElement().removeChild(signatureNode);
        newDoc.getDocumentElement().insertBefore(signatureNode, subjectNode);
      }
    }

    // Now let us import this signed doc into the original document we got in the method call
    Node signedNode = doc.importNode(newDoc.getFirstChild(), true);

    if (!referenceURI.isEmpty()) {
      propagateIDAttributeSetup(newDoc.getDocumentElement(), (Element) signedNode);
    }

    parentNode.replaceChild(signedNode, nodeToBeSigned);
    // doc.getDocumentElement().replaceChild(signedNode, nodeToBeSigned);

    return doc;
  }
  public String buildHtmlPostResponse(Document responseDoc, String actionUrl, boolean asRequest)
      throws ProcessingException, ConfigurationException, IOException {
    byte[] responseBytes =
        org.keycloak.saml.common.util.DocumentUtil.getDocumentAsString(responseDoc)
            .getBytes("UTF-8");
    String samlResponse = PostBindingUtil.base64Encode(new String(responseBytes));

    return buildHtml(samlResponse, actionUrl, asRequest);
  }
  /**
   * Sign the root element
   *
   * @param doc
   * @param signingKey
   * @param publicKey
   * @param digestMethod
   * @param signatureMethod
   * @param referenceURI
   * @return
   * @throws GeneralSecurityException
   * @throws XMLSignatureException
   * @throws MarshalException
   * @since 2.5.0
   */
  public static Document sign(
      Document doc,
      KeyPair keyPair,
      String digestMethod,
      String signatureMethod,
      String referenceURI,
      X509Certificate x509Certificate)
      throws GeneralSecurityException, MarshalException, XMLSignatureException {
    logger.trace("Document to be signed=" + DocumentUtil.asString(doc));
    PrivateKey signingKey = keyPair.getPrivate();
    PublicKey publicKey = keyPair.getPublic();

    DOMSignContext dsc = new DOMSignContext(signingKey, doc.getDocumentElement());

    signImpl(dsc, digestMethod, signatureMethod, referenceURI, publicKey, x509Certificate);

    return doc;
  }
  /**
   * Sign the root element
   *
   * @param doc
   * @param signingKey
   * @param publicKey
   * @param digestMethod
   * @param signatureMethod
   * @param referenceURI
   * @return
   * @throws GeneralSecurityException
   * @throws XMLSignatureException
   * @throws MarshalException
   */
  public static Document sign(SignatureUtilTransferObject dto)
      throws GeneralSecurityException, MarshalException, XMLSignatureException {
    Document doc = dto.getDocumentToBeSigned();
    KeyPair keyPair = dto.getKeyPair();
    Node nextSibling = dto.getNextSibling();
    String digestMethod = dto.getDigestMethod();
    String referenceURI = dto.getReferenceURI();
    String signatureMethod = dto.getSignatureMethod();

    logger.trace("Document to be signed=" + DocumentUtil.asString(doc));

    PrivateKey signingKey = keyPair.getPrivate();
    PublicKey publicKey = keyPair.getPublic();

    DOMSignContext dsc = new DOMSignContext(signingKey, doc.getDocumentElement(), nextSibling);

    signImpl(dsc, digestMethod, signatureMethod, referenceURI, publicKey, dto.getX509Certificate());

    return doc;
  }
 /**
  * Marshall the signed document to an output stream
  *
  * @param signedDocument
  * @param os
  * @throws TransformerException
  */
 public static void marshall(Document signedDocument, OutputStream os)
     throws TransformerException {
   TransformerFactory tf = TransformerUtil.getTransformerFactory();
   Transformer trans = tf.newTransformer();
   trans.transform(DocumentUtil.getXMLSource(signedDocument), new StreamResult(os));
 }