4

我有一个初始化 CXF Web 服务并用签名检查包装它的 spring 上下文:

<bean id="myProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="ignoreResourceNotFound" value="true"/>
    <property name="locations">
        <list>
            <value>classpath:my.properties</value>
        </list>
    </property>
</bean>

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="ignoreResourceNotFound" value="true"/>
    <property name="properties" ref="myProperties"/>
    <property name="placeholderPrefix" value="!sp{"/>
    <property name="placeholderSuffix" value="}"/>
</bean>

<bean id="inbound-security" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
    <constructor-arg>
        <map>
            <entry key="action" value="Signature"/>
            <entry key="signaturePropFile" value="!sp{acq.signature.properties.location}"/>
        </map>
    </constructor-arg>
</bean>

我意识到signaturePropFile必须在类路径上,它不能从文件系统中读取:-(

Caused by: org.apache.ws.security.WSSecurityException: General security error (Cannot load the resource D:\Dev\Projekty\smartpos-backend-parent\smartpos-backend-acquirer\src\main\resources\signature.properties)
at org.apache.ws.security.components.crypto.CryptoFactory.getProperties(CryptoFactory.java:261) ~[wss4j-1.6.11.jar:1.6.11]
at org.apache.ws.security.components.crypto.CryptoFactory.getInstance(CryptoFactory.java:186) ~[wss4j-1.6.11.jar:1.6.11]
at org.apache.cxf.ws.security.wss4j.AbstractWSS4JInterceptor.loadCryptoFromPropertiesFile(AbstractWSS4JInterceptor.java:224) ~[cxf-rt-ws-security-2.7.5.jar:2.7.5]
at org.apache.ws.security.handler.WSHandler.loadCrypto(WSHandler.java:911) ~[wss4j-1.6.11.jar:1.6.11]

没关系,我让它成为部署的一部分,但我确实想外部化密钥库,它是用以下属性定义的:

org.apache.ws.security.crypto.merlin.keystore.file=server-keystore.jks

我试图用一些配置属性!sp{keystore.location}和替换路径${keystore.location},但它不起作用。事实上,它失败了,就像属性文件不存在一样:

Caused by: org.apache.ws.security.WSSecurityException: General security error (Cannot load the resource classpath:signature.properties)
at org.apache.ws.security.components.crypto.CryptoFactory.getProperties(CryptoFactory.java:261) ~[wss4j-1.6.11.jar:1.6.11]
at org.apache.ws.security.components.crypto.CryptoFactory.getInstance(CryptoFactory.java:186) ~[wss4j-1.6.11.jar:1.6.11]
at org.apache.cxf.ws.security.wss4j.AbstractWSS4JInterceptor.loadCryptoFromPropertiesFile(AbstractWSS4JInterceptor.java:224) ~[cxf-rt-ws-security-2.7.5.jar:2.7.5]
at org.apache.ws.security.handler.WSHandler.loadCrypto(WSHandler.java:911) ~[wss4j-1.6.11.jar:1.6.11]

配置 WSS4J 密钥库位置的正确方法是什么?我不喜欢在部署前编辑战争。(我使用 Maven 来构建它)。

4

3 回答 3

3

不确定它是否会有所帮助,但我有一个类似的目标:我想指向我的 jar 之外的密钥库,因为它取决于最终用户证书。

假设您的 Manifest.mf 具有此类路径设置:

类路径:.

您可以简单地定位与 jar 相同目录中的外部文件夹。就我而言,我执行以下操作:

org.apache.ws.security.crypto.merlin.file=config-folder/mycert.jks

配置文件夹与我的application.jar文件位于同一目录中。

于 2015-01-20T13:31:14.937 回答
3

这个问题最近已经解决了。

当使用旧版本的 wss4j(v2.1.1 和更早版本)时,您可以通过覆盖 WSHandler.loadCrypto() 并通过 Spring util 注入创建的 Property 对象来传递对属性文件(例如 WSHandlerConstants.SIG_PROP_REF_ID)的字符串引用的需要,例如:

<util:properties id="wss4jCryptoProperties">
    <prop key="org.apache.ws.security.crypto.merlin.keystore.file">!sp{keystore.file}</prop>
    <prop key="org.apache.ws.security.crypto.merlin.keystore.type">!sp{keystore.type}</prop>
    <prop key="org.apache.ws.security.crypto.merlin.keystore.password">!sp{keystore.password}</prop>
</util:properties>

通过示例覆盖 WSHandler.loadCrypto() :

public class PropertiesWSS4JInInterceptor extends WSS4JInInterceptor {

    private Properties cryptoProperties;

    public PropertiesWSS4JInInterceptor(Map<String, Object> inProps,
                                        Properties cryptoProperties) {
        super(inProps);
        this.cryptoProperties = cryptoProperties;
    }

    @Override
    protected Crypto loadCrypto(String cryptoPropertyFile, String cryptoPropertyRefId,
                                RequestData requestData) throws WSSecurityException {
        return CryptoFactory.getInstance(cryptoProperties);
    }
}

此外,您可以在 customBean 中注入 wss4jCryptoProperties(不要忘记在引用的类和 setter 中创建名为 cryptoProperties 的字段):

<bean id="customBean" class="cz.company.CustomBean">
    <property name="cryptoProperties" ref="wss4jCryptoProperties"/>
</bean>

最后,您可以将拦截器添加到您的端点:

endpoint.getInInterceptors().add(new PropertiesWSS4JInInterceptor(inProps, cryptoProperties));
于 2015-12-15T10:29:45.510 回答
0

我正在使用此页面来解决我从外部文件夹引用它的问题。实际上在转换属性 *org.apache.ws.security.crypto.merlin.keystore.file * 的路径时,它被馈送到文件系统。文件路径) -

Merlin.java:333

实际上可以从外部文件夹解密文件的路径。无需做额外的工作。

org.apache.ws.security.crypto.merlin.keystore.file=/usr/local/path/server-keystore.jks 有效!!!

于 2018-12-25T16:39:47.543 回答