You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apache Camel中XML Security组件实现分离式XML签名的Schema配置问题

问题:Apache Camel分离式XML签名无法生成验证Schema,指定元素签名失效

我在实现**分离式XML签名(Detached XML Signatures)**时碰到了两个棘手的问题:

  1. 按照官方示例配置后,始终无法生成用于验证的test.xsd Schema文件
  2. 尝试对已加密请求里的Body、Timestamp和BinarySecurityToken三个元素签名,但配置后完全没达到预期效果

以下是我的Camel Blueprint路由配置、待签名元素配置,以及截断的签名URI:

完整路由配置

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:camel="http://camel.apache.org/schema/blueprint" xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0" xmlns:cxf="http://camel.apache.org/schema/blueprint/cxf" xmlns:http="http://cxf.apache.org/transports/http/configuration" xmlns:sec="http://cxf.apache.org/configuration/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd"> 
    <camel:keyStoreParameters id="injks" password="desarrollo" resource="C:/Users/Usuario/Desktop/nuevo/test.jks"/> 
    <bean class="org.apache.camel.util.jsse.KeyStoreParameters" id="keyStore2"> 
        <property name="resource" value="C:/Users/Usuario/Desktop/nuevo/test.jks"/> 
        <property name="password" value="development"/> 
    </bean> 
    <bean class="org.apache.camel.component.xmlsecurity.api.DefaultKeyAccessor" id="keyAccessorOne"> 
        <property name="alias" value="test"/> 
        <property name="password" value="development"/> 
        <property name="keyStoreParameters" ref="keyStore2"/> 
    </bean> 
    <!-- Parts --> 
    <bean class="java.util.ArrayList" id="xpathParts"> 
        <argument> 
            <list> 
                <bean class="org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper" factory-method="getXpathFilter"> 
                    <argument type="java.lang.String" value="//*:Body"/> 
                </bean> 
                <bean class="org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper" factory-method="getXpathFilter"> 
                    <argument type="java.lang.String" value="//*:Timestamp"/> 
                </bean> 
                <bean class="org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper" factory-method="getXpathFilter"> 
                    <argument type="java.lang.String" value="//*:BinarySecurityToken"/> 
                </bean> 
            </list> 
        </argument> 
    </bean> 
    <camelContext id="context-redbanc" xmlns="http://camel.apache.org/schema/blueprint"> 
        <route id="_route1"> 
            <from id="_from1" uri="timer:foo?period=20000"/> 
            <setBody id="_setBody1"> 
                <simple>resource:classpath:etc/wsdl/schema.xml</simple> 
            </setBody> 
            <marshal id="_marshal2"> 
                <jaxb contextPath="cl.coopeuch.integracion.wsredbanc.wsdl.test"/> 
            </marshal> 
            <marshal id="_marshal1"> 
                <secureXML id="inEncryption" keyCipherAlgorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" keyOrTrustStoreParametersId="injks" recipientKeyAlias="des-wls02.rbc.cl" secureTag="//*:Body" secureTagContents="true" xmlCipherAlgorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/> 
            </marshal> 
            <setHeader headerName="CamelXmlSignatureContentReferenceUri" id="_setHeader1"> 
                <constant>#Body</constant> 
            </setHeader> 
            <to id="_to2" uri="xmlsecurity:sign://oneSign?keyAccessor=#keyAccessorOne&amp;amp;digestAlgorithm=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23sha1&amp;amp;xpathsToIdAttributes=#xpathParts&amp;amp;schemaResourceUri=etc/wsdl/schema.xsd"/> 
            <to id="_to3" uri="file://C:/Users/Usuario/Desktop/salida?fileName=outbound_body.xml"/> 
            <to id="_to4" uri="mock:result"/> 
        </route> 
    </camelContext> 
</blueprint>

待签名元素配置

<bean class="java.util.ArrayList" id="xpathParts"> 
    <argument> 
        <list> 
            <bean class="org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper" factory-method="getXpathFilter"> 
                <argument type="java.lang.String" value="//*:Body"/> 
            </bean> 
            <bean class="org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper" factory-method="getXpathFilter"> 
                <argument type="java.lang.String" value="//*:Timestamp"/> 
            </bean> 
            <bean class="org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper" factory-method="getXpathFilter"> 
                <argument type="java.lang.String" value="//*:BinarySecurityToken"/> 
            </bean> 
        </list> 
    </argument> 
</bean>

截断的签名URI

<to id="_to2" uri="xmlsecurity:sign://oneSign?keyAccessor=#keyAccessorOne&amp;amp;digestAlgorithm=http%3A%2F%2Fwww.w3.org%2F200"/>

问题排查与修正方案

1. Schema生成失败的核心原因与解决

  • 路径与参数配置问题:你指定的schemaResourceUri=etc/wsdl/schema.xsd必须确保文件在Camel的类路径下(比如打包后要在META-INF或指定资源目录),同时需要添加generateSchema=true参数明确开启Schema生成(默认是关闭的)
  • 加密后结构影响:加密后的Body会被<xenc:EncryptedData>包裹,原XPath可能无法匹配,导致组件无法正确解析结构生成Schema,需要先确认加密后的XML结构是否符合预期

2. 指定元素签名失效的修正

你的配置里犯了一个关键错误:xpathsToIdAttributes参数是用来给指定元素添加ID属性的,不是用来指定待签名元素的。要指定签名部分,应该用xmlSignatureParts参数,配合XmlSignatureHelper.getSignaturePart()方法创建签名项:

修正后的待签名元素配置

<bean class="java.util.ArrayList" id="signatureParts">
    <argument>
        <list>
            <!-- 签名Body元素(注意加密后可能需要调整XPath) -->
            <bean class="org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper" factory-method="getSignaturePart">
                <argument type="java.lang.String" value="//*:Body"/>
                <argument type="java.lang.String" value="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
            </bean>
            <!-- 签名Timestamp元素 -->
            <bean class="org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper" factory-method="getSignaturePart">
                <argument type="java.lang.String" value="//*:Timestamp"/>
                <argument type="java.lang.String" value="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
            </bean>
            <!-- 签名BinarySecurityToken元素 -->
            <bean class="org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper" factory-method="getSignaturePart">
                <argument type="java.lang.String" value="//*:BinarySecurityToken"/>
                <argument type="java.lang.String" value="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
            </bean>
        </list>
    </argument>
</bean>

修正后的完整签名URI

添加分离式签名类型、Schema生成参数,替换正确的签名部分参数:

<to id="_to2" uri="xmlsecurity:sign://oneSign?keyAccessor=#keyAccessorOne&amp;digestAlgorithm=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23sha1&amp;xmlSignatureParts=#signatureParts&amp;signatureType=DETACHED&amp;schemaResourceUri=etc/wsdl/schema.xsd&amp;generateSchema=true"/>

加密后Body的XPath调整

如果加密后的Body被<xenc:EncryptedData>包裹,你需要修改XPath并在加密配置中指定ID:

<!-- 加密配置添加secureTagId -->
<marshal id="_marshal1">
    <secureXML id="inEncryption" keyCipherAlgorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" keyOrTrustStoreParametersId="injks" recipientKeyAlias="des-wls02.rbc.cl" secureTag="//*:Body" secureTagId="Body-Encrypted" secureTagContents="true" xmlCipherAlgorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
</marshal>

<!-- 签名部分的XPath改为匹配加密后的节点 -->
<bean class="org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper" factory-method="getSignaturePart">
    <argument type="java.lang.String" value="//xenc:EncryptedData[@Id='Body-Encrypted']"/>
    <argument type="java.lang.String" value="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</bean>

额外调试建议

开启Camel的DEBUG日志级别,查看org.apache.camel.component.xmlsecurity包下的日志,能清晰看到元素匹配、签名生成、Schema生成的详细过程,快速定位问题点。另外建议先测试未加密的XML签名,确认签名逻辑正常后再加入加密步骤,分步排查更高效。

内容的提问来源于stack exchange,提问作者ctoledo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:19:07