diff --git a/security/src/main/java/org/springframework/ws/soap/security/wss4j/support/CryptoFactoryBean.java b/security/src/main/java/org/springframework/ws/soap/security/wss4j/support/CryptoFactoryBean.java index 3991f031..46558eeb 100755 --- a/security/src/main/java/org/springframework/ws/soap/security/wss4j/support/CryptoFactoryBean.java +++ b/security/src/main/java/org/springframework/ws/soap/security/wss4j/support/CryptoFactoryBean.java @@ -16,21 +16,26 @@ package org.springframework.ws.soap.security.wss4j.support; +import java.io.File; +import java.io.IOException; import java.util.Properties; import org.apache.ws.security.components.crypto.Crypto; import org.apache.ws.security.components.crypto.CryptoFactory; +import org.apache.ws.security.components.crypto.Merlin; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; +import org.springframework.core.io.Resource; import org.springframework.util.Assert; /** - * Spring factory bean for a WSS4J {@link Crypto}. + * Spring factory bean for a WSS4J {@link Crypto}. Allows for strong-typed property configuration, or configuration + * through {@link Properties}. *

- * Requires the {@link #setConfiguration(java.util.Properties) configuration} property to be set. This configuration - * should have the org.apache.ws.security.crypto.provider property defined. + * Requires either individual properties, or the {@link #setConfiguration(java.util.Properties) configuration} property + * to be set. * * @author Tareq Abed Rabbo * @author Arjen Poutsma @@ -39,19 +44,109 @@ import org.springframework.util.Assert; */ public class CryptoFactoryBean implements FactoryBean, BeanClassLoaderAware, InitializingBean { - private Properties configuration; + private Properties configuration = new Properties(); private ClassLoader classLoader; private Crypto crypto; + private static final String CRYPTO_PROVIDER_PROPERTY = "org.apache.ws.security.crypto.provider"; + /** - * Sets the configuration of the Crypto. + * Sets the configuration of the Crypto. Setting this property overrides all previously set configuration, through + * the type-safe properties * * @see org.apache.ws.security.components.crypto.CryptoFactory#getInstance(java.util.Properties) */ public void setConfiguration(Properties properties) { - this.configuration = properties; + Assert.notNull(properties, "'properties' must not be null"); + this.configuration.putAll(properties); + } + + /** + * Sets the {@link org.apache.ws.security.components.crypto.Crypto} provider name. Defaults to {@link + * org.apache.ws.security.components.crypto.Merlin}. + *

+ * This property maps to the WSS4J org.apache.ws.security.crypto.provider property. + * + * @param cryptoProviderClass the crypto provider class + */ + public void setCryptoProvider(Class cryptoProviderClass) { + this.configuration.setProperty(CRYPTO_PROVIDER_PROPERTY, cryptoProviderClass.getName()); + } + + /** + * Sets the location of the key store to be loaded in the {@link org.apache.ws.security.components.crypto.Crypto} + * instance. + *

+ * This property maps to the WSS4J org.apache.ws.security.crypto.merlin.file property. + * + * @param location the key store location + * @throws java.io.IOException when the resource cannot be openened + */ + public void setKeyStoreLocation(Resource location) throws IOException { + File keystoreFile = location.getFile(); + this.configuration.setProperty("org.apache.ws.security.crypto.merlin.file", keystoreFile.getAbsolutePath()); + } + + /** + * Sets the key store provider. + *

+ * This property maps to the WSS4J org.apache.ws.security.crypto.merlin.keystore.provider property. + * + * @param provider the key store provider + */ + public void setKeyStoreProvider(String provider) { + this.configuration.setProperty("org.apache.ws.security.crypto.merlin.keystore.provider", provider); + } + + /** + * Sets the key store password. Defaults to security. + *

+ * This property maps to the WSS4J org.apache.ws.security.crypto.merlin.keystore.password property. + * + * @param password the key store password + */ + public void setKeyStorePassword(String password) { + this.configuration.setProperty("org.apache.ws.security.crypto.merlin.keystore.password", password); + } + + /** + * Sets the key store type. Defaults to {@link java.security.KeyStore#getDefaultType()}. + *

+ * This property maps to the WSS4J org.apache.ws.security.crypto.merlin.keystore.type property. + * + * @param type the key store type + */ + public void setKeyStoreType(String type) { + this.configuration.setProperty("org.apache.ws.security.crypto.merlin.keystore.type", type); + } + + /** + * Sets the trust store password. Defaults to changeit. + *

+ * WSS4J crypto uses the standard J2SE trust store, i.e. $JAVA_HOME/lib/security/cacerts. + *

+ *

+ * This property maps to the WSS4J org.apache.ws.security.crypto.merlin.cacerts.password property. + * + * @param password the trust store password + */ + public void setTrustStorePassword(String password) { + this.configuration.setProperty("org.apache.ws.security.crypto.merlin.cacerts.password", password); + } + + /** + * Sets the alias name of the default certificate which has been specified as a property. This should be the + * certificate that is used for signature and encryption. This alias corresponds to the certificate that should be + * used whenever KeyInfo is not present in a signed or an encrypted message. + *

+ * This property maps to the WSS4J org.apache.ws.security.crypto.merlin.keystore.alias property. + * + * @param defaultX509Alias alias name of the default X509 certificate + */ + public void setDefaultX509Alias(String defaultX509Alias) { + this.configuration.setProperty("org.apache.ws.security.crypto.merlin.keystore.alias", defaultX509Alias); } public void setBeanClassLoader(ClassLoader classLoader) { @@ -59,8 +154,9 @@ public class CryptoFactoryBean implements FactoryBean, BeanClassLoaderAware, Ini } public void afterPropertiesSet() throws Exception { - Assert.notNull(configuration, "'configuration' is required"); - + if (!configuration.containsKey(CRYPTO_PROVIDER_PROPERTY)) { + configuration.setProperty(CRYPTO_PROVIDER_PROPERTY, Merlin.class.getName()); + } this.crypto = CryptoFactory.getInstance(configuration, classLoader); } diff --git a/security/src/test/java/org/springframework/ws/soap/security/wss4j/support/CryptoFactoryBeanTest.java b/security/src/test/java/org/springframework/ws/soap/security/wss4j/support/CryptoFactoryBeanTest.java index bc66a6da..1d140d8a 100644 --- a/security/src/test/java/org/springframework/ws/soap/security/wss4j/support/CryptoFactoryBeanTest.java +++ b/security/src/test/java/org/springframework/ws/soap/security/wss4j/support/CryptoFactoryBeanTest.java @@ -19,10 +19,9 @@ package org.springframework.ws.soap.security.wss4j.support; import java.util.Properties; import junit.framework.TestCase; -import org.apache.ws.security.components.crypto.Crypto; +import org.apache.ws.security.components.crypto.Merlin; import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.support.PropertiesLoaderUtils; import org.springframework.util.ClassUtils; public class CryptoFactoryBeanTest extends TestCase { @@ -33,15 +32,31 @@ public class CryptoFactoryBeanTest extends TestCase { factoryBean = new CryptoFactoryBean(); } - public void testMerlin() throws Exception { - Properties configuration = - PropertiesLoaderUtils.loadProperties(new ClassPathResource("merlin.properties", getClass())); + public void testSetConfiguration() throws Exception { + Properties configuration = new Properties(); + configuration.setProperty("org.apache.ws.security.crypto.provider", + "org.apache.ws.security.components.crypto.Merlin"); + configuration.setProperty("org.apache.ws.security.crypto.merlin.keystore.type", "jceks"); + configuration.setProperty("org.apache.ws.security.crypto.merlin.keystore.password", "123456"); + configuration.setProperty("org.apache.ws.security.crypto.merlin.file", "private.jks"); + factoryBean.setConfiguration(configuration); factoryBean.setBeanClassLoader(ClassUtils.getDefaultClassLoader()); factoryBean.afterPropertiesSet(); Object result = factoryBean.getObject(); assertNotNull("No result", result); - assertTrue("Not a crypto instance", result instanceof Crypto); + assertTrue("Not a Merlin instance", result instanceof Merlin); + } + + public void testProperties() throws Exception { + factoryBean.setKeyStoreType("jceks"); + factoryBean.setKeyStorePassword("123456"); + factoryBean.setKeyStoreLocation(new ClassPathResource("private.jks")); + factoryBean.setBeanClassLoader(ClassUtils.getDefaultClassLoader()); + factoryBean.afterPropertiesSet(); + Object result = factoryBean.getObject(); + assertNotNull("No result", result); + assertTrue("Not a Merlin instance", result instanceof Merlin); } } \ No newline at end of file diff --git a/security/src/test/resources/org/springframework/ws/soap/security/wss4j/support/merlin.properties b/security/src/test/resources/org/springframework/ws/soap/security/wss4j/support/merlin.properties deleted file mode 100644 index 0c241d26..00000000 --- a/security/src/test/resources/org/springframework/ws/soap/security/wss4j/support/merlin.properties +++ /dev/null @@ -1,6 +0,0 @@ -org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin -org.apache.ws.security.crypto.merlin.keystore.type=pkcs12 -org.apache.ws.security.crypto.merlin.keystore.password=security -org.apache.ws.security.crypto.merlin.keystore.alias=16c73ab6-b892-458f-abf5-2f875f74882e -org.apache.ws.security.crypto.merlin.alias.password=security -org.apache.ws.security.crypto.merlin.file=org/springframework/ws/soap/security/wss4j/support/x509.PFX.MSFT diff --git a/security/src/test/resources/org/springframework/ws/soap/security/wss4j/support/x509.PFX.MSFT b/security/src/test/resources/org/springframework/ws/soap/security/wss4j/support/x509.PFX.MSFT deleted file mode 100644 index 98be0dfc..00000000 Binary files a/security/src/test/resources/org/springframework/ws/soap/security/wss4j/support/x509.PFX.MSFT and /dev/null differ