Хобрук: Ваш путь к мастерству в программировании

Ссылка для URI не имеет XMLSignatureInput с использованием Apache Santuario

Мне нужно интегрировать мое веб-приложение с SSO. Я получаю ответ SAML с цифровой подписью. Мне сказали, что первый шаг — убедиться, что подпись соответствует содержимому SAML, используя стандартный метод проверки подписи XML.

Я использую Apache Santuario, поскольку стандартный Java XML API не работает с JBOSS 7. https://issues.jboss.org/browse/AS7-4248

Ошибка:

org.apache.xml.security.signature.MissingResourceFailureException: The Reference for URI #973348f8-3980-4403-bede-df6d3f2a0f10 has no XMLSignatureInput
Original Exception was org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot resolve element with ID 973348f8-3980-4403-bede-df6d3f2a0f10
Original Exception was org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot resolve element with ID 973348f8-3980-4403-bede-df6d3f2a0f10
Original Exception was org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot resolve element with ID 973348f8-3980-4403-bede-df6d3f2a0f10
Original Exception was org.apache.xml.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID 973348f8-3980-4403-bede-df6d3f2a0f10
  at org.apache.xml.security.signature.Manifest.verifyReferences(Manifest.java:414)
  at org.apache.xml.security.signature.SignedInfo.verify(SignedInfo.java:259)
  at org.apache.xml.security.signature.XMLSignature.checkSignatureValue(XMLSignature.java:724)
  at org.apache.xml.security.signature.XMLSignature.checkSignatureValue(XMLSignature.java:656)

Единственная помощь, которую я смог найти, заключалась в том, чтобы установить для идентификатора элемента Assertion значение null с помощью setIdAttributeNS(). Я не знаю, как и когда это сделать. Я чувствую, что могу сломать SAML в этот момент. http://comments.gmane.org/gmane.text.xml.security.devel/7609

Фрагмент XML:

<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="http://www.carrier.com" ID="da55c478-f2f6-43b7-ba2f-a130d60abbf8" IssueInstant="2013-05-31T21:33:21Z" Version="2.0">
  <saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://someissuer.com/SAML2/SSO</saml:Issuer>
  <samlp:Status>
    <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success">
    </samlp:StatusCode>
  </samlp:Status>
  <saml:Assertion ID="973348f8-3980-4403-bede-df6d3f2a0f10" IssueInstant="2013-05-31T21:33:21Z" Version="2.0">
    <saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://someissuer.com/SAML2/SSO</saml:Issuer>
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
        <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
        <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
        <Reference URI="#973348f8-3980-4403-bede-df6d3f2a0f10">
          <Transforms>
            <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
            <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
          </Transforms>
          <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
          <DigestValue>DIGEST VALUE</DigestValue>
        </Reference>
      </SignedInfo>
      <SignatureValue xmlns="http://www.w3.org/2000/09/xmldsig#">BIG STRING</SignatureValue>
      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
        <X509Data>
          <X509Certificate>ANOTHER BIG STRING</X509Certificate>
        </X509Data>
      </KeyInfo>
    </ds:Signature>

Код:

// load XML from string
InputSource inputSource = new InputSource( new StringReader(saml) );

DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
f.setNamespaceAware(true);
Document doc = f.newDocumentBuilder().parse(inputSource);

// new xpath
xpath = XPathFactory.newInstance().newXPath();

NodeList signatureNodes = doc.getElementsByTagNameNS(Constants.SignatureSpecNS, "Signature");
if (signatureNodes.getLength() == 0) {
    throw new Exception("Signature NOT found!");
}

Element sigElement = (Element) signatureNodes.item(0);
if (sigElement == null) {
    throw new Exception("Signature element is null!");
    }

    XMLSignature signature = new XMLSignature(sigElement, "");

// key
KeyInfo ki = signature.getKeyInfo();
if (ki == null) {
    throw new Exception("Did not find KeyInfo");
}

// validate 
X509Certificate cert = signature.getKeyInfo().getX509Certificate();
if (cert == null) {
    PublicKey pk = signature.getKeyInfo().getPublicKey();
    if (pk == null) {
        throw new Exception("Did not find Certificate or Public Key");
    }

    valid = signature.checkSignatureValue(pk);
}

else {
    valid = signature.checkSignatureValue(cert);
}
24.03.2014

Ответы:


1

Починил это! Я был очень близок, вот что я сделал.

Мне нужно было сначала получить элемент Assertion и зарегистрировать идентификатор.

// load XML from string
InputSource inputSource = new InputSource( new StringReader(saml) );

// load document
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
docFactory.setNamespaceAware(true);
document = docFactory.newDocumentBuilder().parse(inputSource);

// create xpath with appropriate namespace context
xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(new SAMLNamespaceContext());

// load assertion to get signed ID
NodeList assertionNodes = (NodeList) xpath.evaluate("samlp:Response/saml:Assertion", document, XPathConstants.NODESET);
if (assertionNodes.getLength() == 0) {
    throw new Exception("Cannot find Assertion element");
} 

// register ID
Element assertionElement = (Element) assertionNodes.item(0);
assertionElement.setIdAttributeNS(null, "ID", true);

// load signature
NodeList signatureNodes = document.getElementsByTagNameNS(Constants.SignatureSpecNS, "Signature");
if (signatureNodes.getLength() == 0)
    throw new Exception("Signature NOT found!");

Element sigElement = (Element) signatureNodes.item(0);
if (sigElement == null) 
    throw new Exception("Signature element is null!");

XMLSignature signature = new XMLSignature(sigElement, "");

// check for key
KeyInfo ki = signature.getKeyInfo();
if (ki == null) {
    throw new Exception("Did not find KeyInfo");
}

// get cert and validate 
X509Certificate cert = signature.getKeyInfo().getX509Certificate();
if (cert == null) {
    PublicKey pk = signature.getKeyInfo().getPublicKey();
    if (pk == null) {
        throw new Exception("Did not find Certificate or Public Key");
    }

    valid = signature.checkSignatureValue(pk);
}
else {
    valid = signature.checkSignatureValue(cert);
}
26.03.2014
  • Что именно означает регистрационный идентификатор? 03.09.2014
  • Идентификатор регистрации означает регистрацию атрибута, значение которого должно рассматриваться как идентификатор при попытке разрешить узел, связанный с URI, со стилем #‹id› 04.10.2016
  • Новые материалы

    Введение в контекст React
    В этом посте мы поговорим о Context API, который был представлен в React 16, и о том, как вы можете их использовать. Что такое контекст? Глядя на определение из react docs , оно..

    Шлюз с лицензией OSS, совместимый с Apollo Federation v2, появится в WunderGraph
    Сегодня мы рады сообщить, что мы сотрудничаем с поддерживаемой YC Tailor Technologies, Inc. для внедрения Apollo Federation v2. Реализация будет лицензирована MIT (Engine) и Apache 2.0..

    Это оно
    Ну, я официально уволился с работы! На этой неделе я буду лихорадочно выполнять последние требования Думающего , чтобы я мог сосредоточиться на поиске работы. Что именно это значит?..

    7 полезных библиотек JavaScript, которые вы должны использовать в своем следующем проекте
    Усильте свою разработку JavaScript Есть поговорка «Не нужно изобретать велосипед». Библиотеки — лучший тому пример. Это поможет вам написать сложные и трудоемкие функции простым способом...

    Базовое руководство по переносу концепций обучения в глубокое обучение
    Обзор По мере того, как машинное обучение становится все более мощным и продвинутым, модели, обеспечивающие эту расширенную возможность, становятся все больше и начинают требовать огромного..

    C в C.R.U.D с использованием React-Redux
    Если вы использовали React, возможно, вы знакомы с головной болью, связанной с обратным потоком данных. Передача состояния реквизитам от родительских компонентов к дочерним компонентам может..

    5 обязательных элементов современного инструмента конвейера данных
    В цифровом мире предприятия используют конвейеры данных для перемещения, преобразования и хранения огромных объемов данных. Эти конвейеры составляют основу бизнес-аналитики и играют..