Apache camel 为什么Jasypt会尝试解密Camel属性占位符,而不考虑ENC(前缀)?

Apache camel 为什么Jasypt会尝试解密Camel属性占位符,而不考虑ENC(前缀)?,apache-camel,jbossfuse,jasypt,blueprint-osgi,blueprint,Apache Camel,Jbossfuse,Jasypt,Blueprint Osgi,Blueprint,在部署在JBoss Fuse 6.1.0-379中的Blueprint应用程序中,我希望保护用于创建数据库连接的密码。我阅读了这篇文章,并将添加到Blueprint配置中。但是,我的Blueprint配置有许多属性占位符,而且Jasypt占位符解析器似乎正在尝试解密所有我在Camel上下文中定义的占位符。当Blueprint上下文启动时,我得到以下异常: 11:59:51,233 | ERROR | t-379-dmz/deploy | BlueprintCamelContext

在部署在JBoss Fuse 6.1.0-379中的Blueprint应用程序中,我希望保护用于创建数据库连接的密码。我阅读了这篇文章,并将
添加到Blueprint配置中。但是,我的Blueprint配置有许多属性占位符,而且Jasypt占位符解析器似乎正在尝试解密所有我在Camel上下文中定义的占位符。当Blueprint上下文启动时,我得到以下异常:

11:59:51,233 | ERROR | t-379-dmz/deploy | BlueprintCamelContext            | 151 - org.apache.camel.camel-blueprint - 2.12.0.redhat-610379 | Error occurred during starting Camel: CamelContext(camel-5) due Failed to create route route7: Route(route7)[[From[{{uri}}]] -> [Log[logging]]] because of Failed to resolve endpoint: {{uri}} due to: org.jasypt.exceptions.EncryptionOperationNotPossibleException
org.apache.camel.FailedToCreateRouteException: Failed to create route route7: Route(route7)[[From[{{uri}}]] -> [Log[logging]]] because of Failed to resolve endpoint: {{uri}} due to: org.jasypt.exceptions.EncryptionOperationNotPossibleException
    at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:182)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.impl.DefaultCamelContext.startRoute(DefaultCamelContext.java:778)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.impl.DefaultCamelContext.startRouteDefinitions(DefaultCamelContext.java:1955)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.impl.DefaultCamelContext.doStartCamel(DefaultCamelContext.java:1705)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:1579)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.impl.DefaultCamelContext.start(DefaultCamelContext.java:1547)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.blueprint.BlueprintCamelContext.start(BlueprintCamelContext.java:177)[151:org.apache.camel.camel-blueprint:2.12.0.redhat-610379]
    at org.apache.camel.blueprint.BlueprintCamelContext.maybeStart(BlueprintCamelContext.java:209)[151:org.apache.camel.camel-blueprint:2.12.0.redhat-610379]
    at org.apache.camel.blueprint.BlueprintCamelContext.serviceChanged(BlueprintCamelContext.java:147)[151:org.apache.camel.camel-blueprint:2.12.0.redhat-610379]
    at org.apache.felix.framework.util.EventDispatcher.invokeServiceListenerCallback(EventDispatcher.java:934)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
    at org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(EventDispatcher.java:795)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
    at org.apache.felix.framework.util.EventDispatcher.fireServiceEvent(EventDispatcher.java:544)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
    at org.apache.felix.framework.Felix.fireServiceEvent(Felix.java:4666)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
    at org.apache.felix.framework.Felix.registerService(Felix.java:3674)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
    at org.apache.felix.framework.BundleContextImpl.registerService(BundleContextImpl.java:347)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
    at org.apache.aries.blueprint.container.BlueprintContainerImpl.registerService(BlueprintContainerImpl.java:448)[9:org.apache.aries.blueprint.core:1.0.1.redhat-610379]
    at org.apache.aries.blueprint.container.BlueprintContainerImpl.doRun(BlueprintContainerImpl.java:383)[9:org.apache.aries.blueprint.core:1.0.1.redhat-610379]
    at org.apache.aries.blueprint.container.BlueprintContainerImpl.run(BlueprintContainerImpl.java:261)[9:org.apache.aries.blueprint.core:1.0.1.redhat-610379]
    at org.apache.aries.blueprint.container.BlueprintExtender.createContainer(BlueprintExtender.java:270)[9:org.apache.aries.blueprint.core:1.0.1.redhat-610379]
    at org.apache.aries.blueprint.container.BlueprintExtender.modifiedBundle(BlueprintExtender.java:233)[9:org.apache.aries.blueprint.core:1.0.1.redhat-610379]
    at org.apache.aries.util.tracker.hook.BundleHookBundleTracker$Tracked.customizerModified(BundleHookBundleTracker.java:500)[11:org.apache.aries.util:1.0.1.redhat-610379]
    at org.apache.aries.util.tracker.hook.BundleHookBundleTracker$Tracked.customizerModified(BundleHookBundleTracker.java:433)[11:org.apache.aries.util:1.0.1.redhat-610379]
    at org.apache.aries.util.tracker.hook.BundleHookBundleTracker$AbstractTracked.track(BundleHookBundleTracker.java:725)[11:org.apache.aries.util:1.0.1.redhat-610379]
    at org.apache.aries.util.tracker.hook.BundleHookBundleTracker$Tracked.bundleChanged(BundleHookBundleTracker.java:463)[11:org.apache.aries.util:1.0.1.redhat-610379]
    at org.apache.aries.util.tracker.hook.BundleHookBundleTracker$BundleEventHook.event(BundleHookBundleTracker.java:422)[11:org.apache.aries.util:1.0.1.redhat-610379]
    at org.apache.felix.framework.util.SecureAction.invokeBundleEventHook(SecureAction.java:1103)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
    at org.apache.felix.framework.util.EventDispatcher.createWhitelistFromHooks(EventDispatcher.java:696)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
    at org.apache.felix.framework.util.EventDispatcher.fireBundleEvent(EventDispatcher.java:484)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
    at org.apache.felix.framework.Felix.fireBundleEvent(Felix.java:4650)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
    at org.apache.felix.framework.Felix$4.run(Felix.java:2123)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
    at org.apache.felix.framework.Felix.runInContext(Felix.java:2147)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
    at org.apache.felix.framework.Felix.startBundle(Felix.java:2121)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
    at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:955)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
    at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundle(DirectoryWatcher.java:1247)[7:org.apache.felix.fileinstall:3.3.11.redhat-610379]
    at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundles(DirectoryWatcher.java:1219)[7:org.apache.felix.fileinstall:3.3.11.redhat-610379]
    at org.apache.felix.fileinstall.internal.DirectoryWatcher.startAllBundles(DirectoryWatcher.java:1208)[7:org.apache.felix.fileinstall:3.3.11.redhat-610379]
    at org.apache.felix.fileinstall.internal.DirectoryWatcher.process(DirectoryWatcher.java:503)[7:org.apache.felix.fileinstall:3.3.11.redhat-610379]
    at org.apache.felix.fileinstall.internal.DirectoryWatcher.run(DirectoryWatcher.java:291)[7:org.apache.felix.fileinstall:3.3.11.redhat-610379]
Caused by: org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: {{uri}} due to: org.jasypt.exceptions.EncryptionOperationNotPossibleException
    at org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:480)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.util.CamelContextHelper.getMandatoryEndpoint(CamelContextHelper.java:71)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.model.RouteDefinition.resolveEndpoint(RouteDefinition.java:192)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.impl.DefaultRouteContext.resolveEndpoint(DefaultRouteContext.java:106)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.impl.DefaultRouteContext.resolveEndpoint(DefaultRouteContext.java:112)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.model.FromDefinition.resolveEndpoint(FromDefinition.java:72)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.impl.DefaultRouteContext.getEndpoint(DefaultRouteContext.java:88)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:890)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:177)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    ... 38 more
Caused by: org.apache.camel.RuntimeCamelException: org.jasypt.exceptions.EncryptionOperationNotPossibleException
    at org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1363)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.util.ObjectHelper.invokeMethod(ObjectHelper.java:1005)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.blueprint.BlueprintPropertiesParser.parseProperty(BlueprintPropertiesParser.java:137)[151:org.apache.camel.camel-blueprint:2.12.0.redhat-610379]
    at org.apache.camel.component.properties.DefaultPropertiesParser.createPlaceholderPart(DefaultPropertiesParser.java:201)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.component.properties.DefaultPropertiesParser.doParseUri(DefaultPropertiesParser.java:105)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.component.properties.DefaultPropertiesParser.parseUri(DefaultPropertiesParser.java:51)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.component.properties.PropertiesComponent.parseUri(PropertiesComponent.java:160)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.component.properties.PropertiesComponent.parseUri(PropertiesComponent.java:119)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.impl.DefaultCamelContext.resolvePropertyPlaceholders(DefaultCamelContext.java:1155)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    at org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:478)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    ... 46 more
Caused by: org.jasypt.exceptions.EncryptionOperationNotPossibleException
    at org.jasypt.encryption.pbe.StandardPBEByteEncryptor.decrypt(StandardPBEByteEncryptor.java:918)
    at org.jasypt.encryption.pbe.StandardPBEStringEncryptor.decrypt(StandardPBEStringEncryptor.java:725)
    at org.apache.karaf.jaas.jasypt.handler.EncryptablePropertyPlaceholder.getProperty(EncryptablePropertyPlaceholder.java:38)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)[:1.7.0_25]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)[:1.7.0_25]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[:1.7.0_25]
    at java.lang.reflect.Method.invoke(Method.java:606)[:1.7.0_25]
    at org.apache.camel.util.ObjectHelper.invokeMethod(ObjectHelper.java:1001)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
    ... 54 more
我创建了一个带有Blueprint上下文的测试包,该测试包只包含在Camel上下文中定义的一个占位符属性,而没有使用加密的ENC()占位符语法。我刚刚添加了
,包启动失败,出现了相同的异常(
org.jasypt.exceptions.EncryptionOperationNotableException

这是你想要的行为吗

我的蓝图配置:

<?xml version="1.0" encoding="UTF-8"?> 
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
           xmlns:enc="http://karaf.apache.org/xmlns/jasypt/v1.0.0"
           xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0">


    <cm:property-placeholder persistent-id="encrypt.config" update-strategy="reload" >
        <cm:default-properties>
            <cm:property name="uri" value="timer://foo?fixedRate=true&amp;period=6000"/>
        </cm:default-properties>
    </cm:property-placeholder>

    <enc:property-placeholder>
        <enc:encryptor class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
            <property name="config">
                <bean class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig">
                    <property name="algorithm" value="PBEWithMD5AndDES" />
                    <property name="password" value="password" />
                </bean>
            </property>
        </enc:encryptor>
    </enc:property-placeholder>

     <camelContext xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xmlns="http://camel.apache.org/schema/blueprint"
                  xsi:schemaLocation="http://camel.apache.org/schema/blueprint">
        <route>
            <from uri="{{uri}}"/>
            <log message="logging" loggingLevel="INFO" id="logBeforeService"></log>
        </route>
     </camelContext>

</blueprint>

编辑:来自RedHat支持部门的响应

因此,这是一个已知的问题,并且有几个Jira问题(和),而且这个问题似乎已经在较新版本的Camel中得到了解决。我已经使用名为jboss-fuse-6.1.0.redhat-379-r1p3的补丁程序提供的版本2.12.0.redhat-611412进行了测试,并且不再抛出异常

不管我之前说了什么,我对这个实现非常满意。如果它不能解密一个实际加密的值,我希望抛出一个异常,而这正是发生的情况。我将加密值修改为ENC(无效和应该抛出异常),并引发了一个异常,与我预期的完全相同

Caused by: org.jasypt.exceptions.EncryptionOperationNotPossibleException
编辑:更简洁的答案

就解析属性占位符值的方式而言,Camel Blueprint的行为与Camel Core不同。Camel Core要求开发人员为Camel属性语法定义一个Camel属性占位符解析程序,该解析程序解析Camel上下文中的属性[1]。显然,这背后的原因是为了避免spring属性语法[2]和Camel简单表达式语言语法[3]之间的冲突。开发人员可以选择通过添加额外的配置,将spring属性占位符解析器与Camel连接起来

[1-Camel属性语法]

{{org.my.prop}}
${org.my.prop}
ENC(encrypted.value)
[2-Spring属性语法]

{{org.my.prop}}
${org.my.prop}
ENC(encrypted.value)
[3-简单表达式语言语法]

${exchange.body}
在Camel Blueprint中,Blueprint属性占位符解析程序和Camel上下文之间的桥接会自动发生。创建Blueprint Camel上下文时,会将Blueprint捆绑包上下文注入其中。使用Blueprint捆绑包上下文,Camel会从中取出所有bean,并确定它们是否可分配给pache Aries实现AbstractPropertyPlaceholder。对于您定义的每个属性占位符解析程序的实例,Camel就能够对它们调用resolveProperty方法,而无需解析每个解析程序定义的属性语法

因为Jasypt属性占位符解析器需要占位符语法[4],它只会忽略与此语法匹配的所有内容。因为Camel Blueprint通过了确保属性语法的验证,所以我们最终会遇到这样一种情况:Camel告诉Jasypt占位符解析器解密我们尝试在Camel上下文中使用的每个属性。这当然会引发异常,因为'您正在尝试解密尚未加密的属性

[4-Jasypt Blueprint属性语法]

{{org.my.prop}}
${org.my.prop}
ENC(encrypted.value)
解决方案:

  • 创建一个类,该类实现Jasypt StringEncryptor并将StandardPBestingEncryptor作为属性保存。实现的encrypt和decrypt方法调用StandardPBestingEncryptor的encrypt和decrypt方法,但捕获抛出的任何异常

    • 这就是我在原始答案中给出的解决方案
    • 如果无法解密不应忽略的加密值,则这是危险的。捆绑包不应启动,以防止(例如)您的数据库帐户被锁定
  • 在将值传递给占位符解析程序之前手动解密值

    • 您可以创建一个配置服务,在该服务中,您可以从各种来源编译所有配置,手动解密所有加密值,然后将属性作为OSGi服务公开以供共享
    • 我已经放弃了这个设计,它基本上是重新实现由Karaf提供的ConfigurationAdmin服务(加上Karaf不提供的解密),它不如Karaf提供的那样好,因为它无法检测应用程序配置何时发生更改
  • 在运行时解密值。
    • 也不喜欢这样,这要求应用程序知道哪些应用程序属性需要加密
  • 我已经通过我们的支持合同向Redhat提交了一份支持通知单,如果有任何进展,我会及时通知您

    原始答案:

    根据camel文档,在blueprint中,camel能够检测到存在blueprint占位符解析器,并尝试使用它来解析其属性

    问题是,它不关心占位符前缀和后缀是什么,它只是继续使用它而不需要重新命名。Jasypt占位符解析器已经设计好了,因此只有占位符前缀为“ENC”(“and suffix is”)”时才会调用它,记住吗