Преобразование Xpath не работает в Java

Это мой xml-документ. Я хочу подписать только часть идентификатора пользователя, используя подпись xml. Я использую преобразование xpath для выбора этого конкретного элемента.

<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
Version="2.0" IssueInstant="2012-05-22T13:40:52:390" ProtocolBinding="urn:oasis:na
mes:tc:SAML:2.0:bindings:HTTP-POST" AssertionConsumerServiceURL="localhos
t:8080/consumer.jsp">
<UserID>
   xyz
</UserID>
<testing>
   text
</testing>
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
   http://localhost:8080/saml/SProvider.jsp
</saml:Issuer>
</samlp:AuthnRequest>


Я использую следующий код для добавления преобразований:

transformList.add(exc14nTransform);
 transformList.add(fac.newTransform(Transform.XPATH, new XPathFilterParameterSpec("samlp:AuthnRequest/UserID xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"")));


Но я получаю следующее:

Original Exception was javax.xml.transform.TransformerException: Extra illegal t
okens: 'xmlns', ':', 'samlp', '=', '"urn:oasis:names:tc:SAML:2.0:protocol"'


Итак, я попытался удалить часть xmlns.

transformList.add(fac.newTransform(Transform.XPATH, new XPathFilterParameterSpec("samlp:AuthnRequest/UserID")));


Но он подписывает весь документ и выдает следующее сообщение:

com.sun.org.apache.xml.internal.security.utils.CachedXPa
thFuncHereAPI fixupFunctionTable
INFO: Registering Here function


В чем проблема?
РЕДАКТИРОВАТЬ
Как сказал @Jörn Horstmann, сообщение представляет собой просто журнал или что-то в этом роде. Теперь проблема в том, что даже после запроса xpath подписывается весь документ, а не только UserID. Я подтвердил это, изменив значение <testing>element после подписания документа. В результате документ не проходит проверку (если он подписал только часть UserID, то любые изменения, внесенные в <testing>, должны привести к действительной подписи.)


person Ashwin    schedule 22.05.2012    source источник


Ответы (1)


Это недопустимое выражение xpath, внутри выражения нельзя объявить префикс пространства имен.

samlp:AuthnRequest/UserID xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"

XPathFilterParameterSpec имеет другой конструктор, который позволяет указать сопоставление префиксов пространств имен, вы можете попробовать следующее выражение:

new XPathFilterParameterSpec("samlp:AuthnRequest/UserID",
    Collections.singletonMap("samlp", "urn:oasis:names:tc:SAML:2.0:protocol"))

Изменить:

Сообщение не похоже на ошибку, см. строка 426 здесь, хотя его уровень журнала, вероятно, должен быть ниже, чем INFO.

Я также просмотрел описание фильтрации xpath:

Выражение XPath, появляющееся в параметре XPath, оценивается один раз для каждого узла во входном наборе узлов. Результат преобразуется в логическое значение. Если логическое значение истинно, то узел включается в выходной набор узлов. Если логическое значение равно false, то узел исключается из выходного набора узлов.

Таким образом, правильным выражением xpath для включения в подпись только UserID будет self::UserID. Но не спрашивайте меня, действительно ли это имеет смысл для подписи xml. Пример в спецификации, похоже, использует выражение xpath для включения всего, кроме самого элемента подписи:

not(ancestor-or-self::dsig:Signature)

Редактировать 2:

Правильное выражение на самом деле ancestor-or-self::UserID, так как фильтр также должен включать текстовые дочерние узлы узла UserID.

person Jörn Horstmann    schedule 22.05.2012
comment
Спасибо за ответ. Я пробовал. Ошибка недопустимого токена исчезла. Но теперь, после подписания документа, я изменил значение идентификатора пользователя, а затем попытался проверить этот измененный документ. Это полностью подтверждается (это не должно происходить). И я все еще получаю сообщение: com.sun.org.apache.xml.internal.security.utils.CachedXPa thFuncHereAPI fixupFunctionTable INFO: Регистрация здесь функции - person Ashwin; 22.05.2012
comment
Я пробовал samlp:AuthnRequest/self::UserID и samlp:AuthnRequest//self::UserID. Тем не менее он подписывает весь документ. - person Ashwin; 22.05.2012
comment
Можете ли вы также попробовать ancestor-or-self::UserID (без предварительного AuthnRequest)? В противном случае было бы полезно опубликовать ваш полный код для подписи и проверки. - person Jörn Horstmann; 23.05.2012
comment
большое спасибо!! это работает сейчас. в чем проблема с предыдущими запросами? - person Ashwin; 23.05.2012
comment
Выражение xpath проверяется для каждого узла в документе, ваше предыдущее выражение соответствовало бы узлу, имеющему samlp:AuthnRequest в качестве дочернего, а ancestor-or-self::UserID соответствует, если текущий узел UserID, а также для всех его текстовых дочерних узлов. - person Jörn Horstmann; 23.05.2012
comment
У меня есть еще одна проблема. Я хочу использовать преобразование xslt в качестве последнего преобразования. преобразование xslt предназначено для целей рендеринга. Как добавить преобразование xslt после преобразования xpath в java? Вы хотите, чтобы я разместил отдельный вопрос для этого? - person Ashwin; 23.05.2012
comment
Я думаю, что это было бы лучше, как отдельный вопрос. - person Jörn Horstmann; 23.05.2012