1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.ws.soap.security;
18
19 import java.util.Locale;
20 import javax.xml.namespace.QName;
21
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24
25 import org.springframework.util.Assert;
26 import org.springframework.ws.client.WebServiceClientException;
27 import org.springframework.ws.client.support.interceptor.ClientInterceptor;
28 import org.springframework.ws.context.MessageContext;
29 import org.springframework.ws.server.EndpointExceptionResolver;
30 import org.springframework.ws.soap.SoapBody;
31 import org.springframework.ws.soap.SoapFault;
32 import org.springframework.ws.soap.SoapHeaderElement;
33 import org.springframework.ws.soap.SoapMessage;
34 import org.springframework.ws.soap.server.SoapEndpointInterceptor;
35 import org.springframework.ws.soap.soap11.Soap11Body;
36
37
38
39
40
41
42
43
44
45
46
47
48
49 public abstract class AbstractWsSecurityInterceptor implements SoapEndpointInterceptor, ClientInterceptor {
50
51
52 protected final Log logger = LogFactory.getLog(getClass());
53
54 protected static final QName WS_SECURITY_NAME =
55 new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security");
56
57 private boolean secureResponse = true;
58
59 private boolean validateRequest = true;
60
61 private boolean secureRequest = true;
62
63 private boolean validateResponse = true;
64
65 private EndpointExceptionResolver exceptionResolver;
66
67
68 public void setValidateRequest(boolean validateRequest) {
69 this.validateRequest = validateRequest;
70 }
71
72
73 public void setSecureResponse(boolean secureResponse) {
74 this.secureResponse = secureResponse;
75 }
76
77
78 public void setSecureRequest(boolean secureRequest) {
79 this.secureRequest = secureRequest;
80 }
81
82
83 public void setValidateResponse(boolean validateResponse) {
84 this.validateResponse = validateResponse;
85 }
86
87
88 public void setExceptionResolver(EndpointExceptionResolver exceptionResolver) {
89 this.exceptionResolver = exceptionResolver;
90 }
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106 public final boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {
107 if (validateRequest) {
108 Assert.isInstanceOf(SoapMessage.class, messageContext.getRequest());
109 try {
110 validateMessage((SoapMessage) messageContext.getRequest(), messageContext);
111 return true;
112 }
113 catch (WsSecurityValidationException ex) {
114 return handleValidationException(ex, messageContext);
115 }
116 catch (WsSecurityFaultException ex) {
117 return handleFaultException(ex, messageContext);
118 }
119 }
120 else {
121 return true;
122 }
123 }
124
125
126
127
128
129
130
131
132
133
134
135 public final boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {
136 boolean result = true;
137 try {
138 if (secureResponse) {
139 Assert.isTrue(messageContext.hasResponse(), "MessageContext contains no response");
140 Assert.isInstanceOf(SoapMessage.class, messageContext.getResponse());
141 try {
142 secureMessage((SoapMessage) messageContext.getResponse(), messageContext);
143 }
144 catch (WsSecuritySecurementException ex) {
145 result = handleSecurementException(ex, messageContext);
146 }
147 catch (WsSecurityFaultException ex) {
148 result = handleFaultException(ex, messageContext);
149 }
150 }
151 }
152 finally {
153 if (!result) {
154 messageContext.clearResponse();
155 }
156 cleanUp();
157 }
158 return result;
159 }
160
161
162 public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {
163 cleanUp();
164 return true;
165 }
166
167 public boolean understands(SoapHeaderElement headerElement) {
168 return WS_SECURITY_NAME.equals(headerElement.getName());
169 }
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184 public final boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {
185 if (secureRequest) {
186 Assert.isInstanceOf(SoapMessage.class, messageContext.getRequest());
187 try {
188 secureMessage((SoapMessage) messageContext.getRequest(), messageContext);
189 return true;
190 }
191 catch (WsSecuritySecurementException ex) {
192 return handleSecurementException(ex, messageContext);
193 }
194 catch (WsSecurityFaultException ex) {
195 return handleFaultException(ex, messageContext);
196 }
197 }
198 else {
199 return true;
200 }
201 }
202
203
204
205
206
207
208
209
210
211
212 public final boolean handleResponse(MessageContext messageContext) throws WebServiceClientException {
213 if (validateResponse) {
214 Assert.isTrue(messageContext.hasResponse(), "MessageContext contains no response");
215 Assert.isInstanceOf(SoapMessage.class, messageContext.getResponse());
216 try {
217 validateMessage((SoapMessage) messageContext.getResponse(), messageContext);
218 return true;
219 }
220 catch (WsSecurityValidationException ex) {
221 return handleValidationException(ex, messageContext);
222 }
223 catch (WsSecurityFaultException ex) {
224 return handleFaultException(ex, messageContext);
225 }
226 }
227 else {
228 return true;
229 }
230 }
231
232
233 public boolean handleFault(MessageContext messageContext) throws WebServiceClientException {
234 return true;
235 }
236
237
238
239
240
241
242
243
244
245 protected boolean handleSecurementException(WsSecuritySecurementException ex, MessageContext messageContext) {
246 if (logger.isErrorEnabled()) {
247 logger.error("Could not secure response: " + ex.getMessage(), ex);
248 }
249 return false;
250 }
251
252
253
254
255
256
257
258
259
260
261 protected boolean handleValidationException(WsSecurityValidationException ex, MessageContext messageContext) {
262 if (logger.isWarnEnabled()) {
263 logger.warn("Could not validate request: " + ex.getMessage());
264 }
265 if (exceptionResolver != null) {
266 exceptionResolver.resolveException(messageContext, null, ex);
267 }
268 else {
269 if (logger.isDebugEnabled()) {
270 logger.debug("No exception resolver present, creating basic soap fault");
271 }
272 SoapBody response = ((SoapMessage) messageContext.getResponse()).getSoapBody();
273 response.addClientOrSenderFault(ex.getMessage(), Locale.ENGLISH);
274 }
275 return false;
276 }
277
278
279
280
281
282
283
284
285
286 protected boolean handleFaultException(WsSecurityFaultException ex, MessageContext messageContext) {
287 if (logger.isWarnEnabled()) {
288 logger.warn("Could not handle request: " + ex.getMessage());
289 }
290 SoapBody response = ((SoapMessage) messageContext.getResponse()).getSoapBody();
291 SoapFault fault;
292 if (response instanceof Soap11Body) {
293 fault = ((Soap11Body) response).addFault(ex.getFaultCode(), ex.getFaultString(), Locale.ENGLISH);
294 }
295 else {
296 fault = response.addClientOrSenderFault(ex.getFaultString(), Locale.ENGLISH);
297 }
298 fault.setFaultActorOrRole(ex.getFaultActor());
299 return false;
300 }
301
302
303
304
305
306
307
308
309 protected abstract void validateMessage(SoapMessage soapMessage, MessageContext messageContext)
310 throws WsSecurityValidationException;
311
312
313
314
315
316
317
318
319 protected abstract void secureMessage(SoapMessage soapMessage, MessageContext messageContext)
320 throws WsSecuritySecurementException;
321
322 protected abstract void cleanUp();
323 }