【问题标题】:Configurable location of keystore in WSS4JWSS4J 中密钥库的可配置位置
【发布时间】:2014-03-12 08:42:56
【问题描述】:

我有一个初始化 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 构建它)。

【问题讨论】:

    标签: java wss4j


    【解决方案1】:

    这个问题已经solved lately

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

    <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));
    

    【讨论】:

      【解决方案2】:

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

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

      类路径:.

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

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

      与我的 application.jar 文件位于同一目录中的 config-folder

      【讨论】:

      • 有趣的想法。我会试一试的。
      【解决方案3】:

      我使用此页面来解决我从外部文件夹引用它的问题。 实际上在转换属性 *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 作品!!!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-25
        • 2010-09-10
        • 2017-06-30
        相关资源
        最近更新 更多