【问题标题】:Xpath transformation not working in javaXpath转换在java中不起作用
【发布时间】:2012-05-28 17:21:12
【问题描述】:

这是我的 xml 文档。我只想使用 xml 签名对用户 ID 部分进行签名。我正在使用 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 查询之后,整个文档都会被签名,而不仅仅是用户 ID。我在签署文件后通过更改&lt;testing&gt;element 的值确认了这一点。结果是文档没有得到验证(如果它只签名了 UserID 部分,那么对 &lt;testing&gt; 所做的任何更改都应该导致有效的签名。)

【问题讨论】:

    标签: java xml xslt xpath xml-signature


    【解决方案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"))
    

    编辑:

    该消息似乎不是错误,请参阅line 426 here,它的日志级别可能应该低于 INFO。

    我还看了description of xpath filtering

    出现在 XPath 参数中的 XPath 表达式为输入节点集中的每个节点计算一次。结果被转换为布尔值。如果布尔值为真,则该节点包含在输出节点集中。如果布尔值为 false,则从输出节点集中省略该节点。

    因此,仅在签名中包含UserID 的正确xpath 表达式为self::UserID。但是不要问我这对于 xml 签名是否真的有意义。规范中的示例似乎使用 xpath 表达式来包含除签名元素本身之外的所有内容:

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

    编辑 2:

    正确的表达式实际上是ancestor-or-self::UserID,因为过滤器还必须包含UserID 节点的文本子节点。

    【讨论】:

    • 感谢您的回复。我尝试过这个。非法令牌错误已经消失。但是现在在签署文件后,我更改了 userID 值,然后尝试验证这个更改的文件。它得到了完全验证(它不应该发生)。而且我仍然收到消息:com.sun.org.apache.xml.internal.security.utils.CachedXPa thFuncHereAPI fixupFunctionTable INFO:Registering Here function
    • 我试过“samlp:AuthnRequest/self::UserID”和“samlp:AuthnRequest//self::UserID”。它仍然签署了整个文件。
    • 你也可以试试ancestor-or-self::UserID(没有前面的AuthnRequest)吗?否则,发布您的完整代码以进行签名和验证会很有用。
    • 非常感谢!!现在可以了。之前的查询有什么问题?
    • xpath 表达式针对文档中的每个节点进行测试,您之前的表达式将匹配具有 samlp:AuthnRequest 作为子节点的节点,而 ancestor-or-self::UserID 匹配当前节点为 UserID以及它的所有文本子节点。
    猜你喜欢
    • 1970-01-01
    • 2018-04-27
    • 1970-01-01
    • 2013-02-10
    • 1970-01-01
    • 1970-01-01
    • 2015-02-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多