|
16 | 16 |
|
17 | 17 | package org.springframework.cloud.bootstrap.encrypt; |
18 | 18 |
|
19 | | -import java.util.ArrayList; |
20 | | -import java.util.Collections; |
21 | | -import java.util.LinkedHashMap; |
22 | | -import java.util.List; |
23 | 19 | import java.util.Map; |
24 | | -import java.util.regex.Pattern; |
25 | | - |
26 | | -import org.apache.commons.logging.Log; |
27 | | -import org.apache.commons.logging.LogFactory; |
28 | 20 |
|
29 | 21 | import org.springframework.boot.SpringApplication; |
30 | 22 | import org.springframework.boot.context.properties.bind.Binder; |
|
33 | 25 | import org.springframework.cloud.bootstrap.TextEncryptorConfigBootstrapper.FailsafeTextEncryptor; |
34 | 26 | import org.springframework.cloud.context.encrypt.EncryptorFactory; |
35 | 27 | import org.springframework.core.Ordered; |
36 | | -import org.springframework.core.env.CompositePropertySource; |
37 | 28 | import org.springframework.core.env.ConfigurableEnvironment; |
38 | | -import org.springframework.core.env.EnumerablePropertySource; |
39 | 29 | import org.springframework.core.env.MutablePropertySources; |
40 | | -import org.springframework.core.env.PropertySource; |
41 | | -import org.springframework.core.env.PropertySources; |
42 | 30 | import org.springframework.core.env.SystemEnvironmentPropertySource; |
43 | 31 | import org.springframework.security.crypto.encrypt.TextEncryptor; |
44 | 32 | import org.springframework.util.ClassUtils; |
|
54 | 42 | * @author Dave Syer |
55 | 43 | * @author Tim Ysewyn |
56 | 44 | */ |
57 | | -public class DecryptEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered { |
58 | | - |
59 | | - /** |
60 | | - * Name of the decrypted property source. |
61 | | - */ |
62 | | - public static final String DECRYPTED_PROPERTY_SOURCE_NAME = "decrypted"; |
63 | | - |
64 | | - /** |
65 | | - * Prefix indicating an encrypted value. |
66 | | - */ |
67 | | - public static final String ENCRYPTED_PROPERTY_PREFIX = "{cipher}"; |
68 | | - |
69 | | - private static final Pattern COLLECTION_PROPERTY = Pattern.compile("(\\S+)?\\[(\\d+)\\](\\.\\S+)?"); |
70 | | - |
71 | | - private static Log logger = LogFactory.getLog(DecryptEnvironmentPostProcessor.class); |
| 45 | +public class DecryptEnvironmentPostProcessor extends AbstractEnvironmentDecrypt implements EnvironmentPostProcessor, Ordered { |
72 | 46 |
|
73 | 47 | private int order = Ordered.LOWEST_PRECEDENCE; |
74 | 48 |
|
75 | | - private boolean failOnError = true; |
76 | | - |
77 | | - /** |
78 | | - * Strategy to determine how to handle exceptions during decryption. |
79 | | - * @param failOnError the flag value (default true) |
80 | | - */ |
81 | | - public void setFailOnError(boolean failOnError) { |
82 | | - this.failOnError = failOnError; |
83 | | - } |
84 | | - |
85 | 49 | @Override |
86 | 50 | public int getOrder() { |
87 | 51 | return this.order; |
@@ -128,101 +92,5 @@ protected TextEncryptor getTextEncryptor(ConfigurableEnvironment environment) { |
128 | 92 | return new FailsafeTextEncryptor(); |
129 | 93 | } |
130 | 94 |
|
131 | | - public Map<String, Object> decrypt(TextEncryptor encryptor, PropertySources propertySources) { |
132 | | - Map<String, Object> properties = merge(propertySources); |
133 | | - decrypt(encryptor, properties); |
134 | | - return properties; |
135 | | - } |
136 | | - |
137 | | - private Map<String, Object> merge(PropertySources propertySources) { |
138 | | - Map<String, Object> properties = new LinkedHashMap<>(); |
139 | | - List<PropertySource<?>> sources = new ArrayList<>(); |
140 | | - for (PropertySource<?> source : propertySources) { |
141 | | - sources.add(0, source); |
142 | | - } |
143 | | - for (PropertySource<?> source : sources) { |
144 | | - merge(source, properties); |
145 | | - } |
146 | | - return properties; |
147 | | - } |
148 | | - |
149 | | - private void merge(PropertySource<?> source, Map<String, Object> properties) { |
150 | | - if (source instanceof CompositePropertySource) { |
151 | | - |
152 | | - List<PropertySource<?>> sources = new ArrayList<>(((CompositePropertySource) source).getPropertySources()); |
153 | | - Collections.reverse(sources); |
154 | | - |
155 | | - for (PropertySource<?> nested : sources) { |
156 | | - merge(nested, properties); |
157 | | - } |
158 | | - |
159 | | - } |
160 | | - else if (source instanceof EnumerablePropertySource) { |
161 | | - Map<String, Object> otherCollectionProperties = new LinkedHashMap<>(); |
162 | | - boolean sourceHasDecryptedCollection = false; |
163 | | - |
164 | | - EnumerablePropertySource<?> enumerable = (EnumerablePropertySource<?>) source; |
165 | | - for (String key : enumerable.getPropertyNames()) { |
166 | | - Object property = source.getProperty(key); |
167 | | - if (property != null) { |
168 | | - String value = property.toString(); |
169 | | - if (value.startsWith(ENCRYPTED_PROPERTY_PREFIX)) { |
170 | | - properties.put(key, value); |
171 | | - if (COLLECTION_PROPERTY.matcher(key).matches()) { |
172 | | - sourceHasDecryptedCollection = true; |
173 | | - } |
174 | | - } |
175 | | - else if (COLLECTION_PROPERTY.matcher(key).matches()) { |
176 | | - // put non-encrypted properties so merging of index properties |
177 | | - // happens correctly |
178 | | - otherCollectionProperties.put(key, value); |
179 | | - } |
180 | | - else { |
181 | | - // override previously encrypted with non-encrypted property |
182 | | - properties.remove(key); |
183 | | - } |
184 | | - } |
185 | | - } |
186 | | - // copy all indexed properties even if not encrypted |
187 | | - if (sourceHasDecryptedCollection && !otherCollectionProperties.isEmpty()) { |
188 | | - properties.putAll(otherCollectionProperties); |
189 | | - } |
190 | | - |
191 | | - } |
192 | | - } |
193 | | - |
194 | | - private void decrypt(TextEncryptor encryptor, Map<String, Object> properties) { |
195 | | - properties.replaceAll((key, value) -> { |
196 | | - String valueString = value.toString(); |
197 | | - if (!valueString.startsWith(ENCRYPTED_PROPERTY_PREFIX)) { |
198 | | - return value; |
199 | | - } |
200 | | - return decrypt(encryptor, key, valueString); |
201 | | - }); |
202 | | - } |
203 | | - |
204 | | - private String decrypt(TextEncryptor encryptor, String key, String original) { |
205 | | - String value = original.substring(ENCRYPTED_PROPERTY_PREFIX.length()); |
206 | | - try { |
207 | | - value = encryptor.decrypt(value); |
208 | | - if (logger.isDebugEnabled()) { |
209 | | - logger.debug("Decrypted: key=" + key); |
210 | | - } |
211 | | - return value; |
212 | | - } |
213 | | - catch (Exception e) { |
214 | | - String message = "Cannot decrypt: key=" + key; |
215 | | - if (logger.isDebugEnabled()) { |
216 | | - logger.warn(message, e); |
217 | | - } |
218 | | - else { |
219 | | - logger.warn(message); |
220 | | - } |
221 | | - if (this.failOnError) { |
222 | | - throw new IllegalStateException(message, e); |
223 | | - } |
224 | | - return ""; |
225 | | - } |
226 | | - } |
227 | 95 |
|
228 | 96 | } |
0 commit comments