View Javadoc

1   /*
2    * Copyright 2005-2011 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.ws.soap.security.wss4j.support;
18  
19  import java.io.IOException;
20  import java.util.Properties;
21  
22  import org.springframework.beans.factory.BeanClassLoaderAware;
23  import org.springframework.beans.factory.FactoryBean;
24  import org.springframework.beans.factory.InitializingBean;
25  import org.springframework.core.io.ClassPathResource;
26  import org.springframework.core.io.Resource;
27  import org.springframework.util.Assert;
28  
29  import org.apache.ws.security.components.crypto.Crypto;
30  import org.apache.ws.security.components.crypto.CryptoFactory;
31  import org.apache.ws.security.components.crypto.Merlin;
32  
33  /**
34   * Spring factory bean for a WSS4J {@link Crypto}. Allows for strong-typed property configuration, or configuration
35   * through {@link Properties}.
36   * <p/>
37   * Requires either individual properties, or the {@link #setConfiguration(java.util.Properties) configuration} property
38   * to be set.
39   *
40   * @author Tareq Abed Rabbo
41   * @author Arjen Poutsma
42   * @see org.apache.ws.security.components.crypto.Crypto
43   * @since 1.5.0
44   */
45  public class CryptoFactoryBean implements FactoryBean<Crypto>, BeanClassLoaderAware, InitializingBean {
46  
47      private Properties configuration = new Properties();
48  
49      private ClassLoader classLoader;
50  
51      private Crypto crypto;
52  
53      private static final String CRYPTO_PROVIDER_PROPERTY = "org.apache.ws.security.crypto.provider";
54  
55      /**
56       * Sets the configuration of the Crypto. Setting this property overrides all previously set configuration, through
57       * the type-safe properties
58       *
59       * @see org.apache.ws.security.components.crypto.CryptoFactory#getInstance(java.util.Properties)
60       */
61      public void setConfiguration(Properties properties) {
62          Assert.notNull(properties, "'properties' must not be null");
63          this.configuration.putAll(properties);
64      }
65  
66      /**
67       * Sets the {@link org.apache.ws.security.components.crypto.Crypto} provider name. Defaults to {@link
68       * org.apache.ws.security.components.crypto.Merlin}.
69       * <p/>
70       * This property maps to the WSS4J {@code org.apache.ws.security.crypto.provider} property.
71       *
72       * @param cryptoProviderClass the crypto provider class
73       */
74      public void setCryptoProvider(Class<? extends Crypto> cryptoProviderClass) {
75          this.configuration.setProperty(CRYPTO_PROVIDER_PROPERTY, cryptoProviderClass.getName());
76      }
77  
78      /**
79       * Sets the location of the key store to be loaded in the {@link org.apache.ws.security.components.crypto.Crypto}
80       * instance.
81       * <p/>
82       * This property maps to the WSS4J {@code org.apache.ws.security.crypto.merlin.file} property.
83       *
84       * @param location the key store location
85       * @throws java.io.IOException when the resource cannot be opened
86       */
87      public void setKeyStoreLocation(Resource location) throws IOException {
88          String resourcePath = getResourcePath(location);
89          this.configuration.setProperty("org.apache.ws.security.crypto.merlin.file", resourcePath);
90      }
91  
92      private String getResourcePath(Resource resource) throws IOException {
93          try {
94              return resource.getFile().getAbsolutePath();
95          }
96          catch (IOException ex) {
97              if (resource instanceof ClassPathResource) {
98                  ClassPathResource classPathResource = (ClassPathResource) resource;
99                  return classPathResource.getPath();
100             }
101             else {
102                 throw ex;
103             }
104         }
105     }
106 
107     /**
108      * Sets the key store provider.
109      * <p/>
110      * This property maps to the WSS4J {@code org.apache.ws.security.crypto.merlin.keystore.provider} property.
111      *
112      * @param provider the key store provider
113      */
114     public void setKeyStoreProvider(String provider) {
115         this.configuration.setProperty("org.apache.ws.security.crypto.merlin.keystore.provider", provider);
116     }
117 
118     /**
119      * Sets the key store password. Defaults to {@code security}.
120      * <p/>
121      * This property maps to the WSS4J {@code org.apache.ws.security.crypto.merlin.keystore.password} property.
122      *
123      * @param password the key store password
124      */
125     public void setKeyStorePassword(String password) {
126         this.configuration.setProperty("org.apache.ws.security.crypto.merlin.keystore.password", password);
127     }
128 
129     /**
130      * Sets the key store type. Defaults to {@link java.security.KeyStore#getDefaultType()}.
131      * <p/>
132      * This property maps to the WSS4J {@code org.apache.ws.security.crypto.merlin.keystore.type} property.
133      *
134      * @param type the key store type
135      */
136     public void setKeyStoreType(String type) {
137         this.configuration.setProperty("org.apache.ws.security.crypto.merlin.keystore.type", type);
138     }
139 
140     /**
141      * Sets the trust store password. Defaults to {@code changeit}.
142      * <p/>
143      * WSS4J crypto uses the standard J2SE trust store, i.e. {@code $JAVA_HOME/lib/security/cacerts}.
144      * <p/>
145      * <p/>
146      * This property maps to the WSS4J {@code org.apache.ws.security.crypto.merlin.cacerts.password} property.
147      *
148      * @param password the trust store password
149      */
150     public void setTrustStorePassword(String password) {
151         this.configuration.setProperty("org.apache.ws.security.crypto.merlin.cacerts.password", password);
152     }
153 
154     /**
155      * Sets the alias name of the default certificate which has been specified as a property. This should be the
156      * certificate that is used for signature and encryption. This alias corresponds to the certificate that should be
157      * used whenever KeyInfo is not present in a signed or an encrypted message.
158      * <p/>
159      * This property maps to the WSS4J {@code org.apache.ws.security.crypto.merlin.keystore.alias} property.
160      *
161      * @param defaultX509Alias alias name of the default X509 certificate
162      */
163     public void setDefaultX509Alias(String defaultX509Alias) {
164         this.configuration.setProperty("org.apache.ws.security.crypto.merlin.keystore.alias", defaultX509Alias);
165     }
166 
167     public void setBeanClassLoader(ClassLoader classLoader) {
168         this.classLoader = classLoader;
169     }
170 
171     public void afterPropertiesSet() throws Exception {
172         if (!configuration.containsKey(CRYPTO_PROVIDER_PROPERTY)) {
173             configuration.setProperty(CRYPTO_PROVIDER_PROPERTY, Merlin.class.getName());
174         }
175         this.crypto = CryptoFactory.getInstance(configuration, classLoader);
176     }
177 
178     public Class<Crypto> getObjectType() {
179         return Crypto.class;
180     }
181 
182     public boolean isSingleton() {
183         return true;
184     }
185 
186     public Crypto getObject() throws Exception {
187         return crypto;
188     }
189 
190 }