Skip to content

Commit 078c390

Browse files
committed
SWS-708 - PayloadValidatingInterceptor errors not clearing SecurityContextHolder, backported to 1.5 branch
1 parent c54076e commit 078c390

File tree

14 files changed

+436
-65
lines changed

14 files changed

+436
-65
lines changed

core/src/main/java/org/springframework/ws/server/EndpointInterceptor.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2005 the original author or authors.
2+
* Copyright 2005-2011 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -96,4 +96,6 @@ public interface EndpointInterceptor {
9696
* blocking of the response handler chain.
9797
*/
9898
boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception;
99+
100+
void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex);
99101
}

core/src/main/java/org/springframework/ws/server/MessageDispatcher.java

Lines changed: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2002-2009 the original author or authors.
2+
* Copyright 2005-2011 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -24,9 +24,6 @@
2424
import java.util.List;
2525
import java.util.Map;
2626

27-
import org.apache.commons.logging.Log;
28-
import org.apache.commons.logging.LogFactory;
29-
3027
import org.springframework.beans.BeansException;
3128
import org.springframework.beans.factory.BeanFactoryUtils;
3229
import org.springframework.beans.factory.BeanNameAware;
@@ -45,27 +42,35 @@
4542
import org.springframework.ws.server.endpoint.MessageEndpoint;
4643
import org.springframework.ws.server.endpoint.PayloadEndpoint;
4744
import org.springframework.ws.server.endpoint.adapter.MessageEndpointAdapter;
48-
import org.springframework.ws.server.endpoint.adapter.MessageMethodEndpointAdapter;
4945
import org.springframework.ws.server.endpoint.adapter.PayloadEndpointAdapter;
50-
import org.springframework.ws.server.endpoint.adapter.PayloadMethodEndpointAdapter;
5146
import org.springframework.ws.soap.server.SoapMessageDispatcher;
5247
import org.springframework.ws.support.DefaultStrategiesHelper;
5348
import org.springframework.ws.transport.WebServiceMessageReceiver;
5449

50+
import org.apache.commons.logging.Log;
51+
import org.apache.commons.logging.LogFactory;
52+
5553
/**
5654
* Central dispatcher for use within Spring-WS, dispatching Web service messages to registered endpoints.
5755
* <p/>
5856
* This dispatcher is quite similar to Spring MVCs {@link DispatcherServlet}. Just like its counterpart, this dispatcher
5957
* is very flexible. This class is SOAP agnostic; in typical SOAP Web Services, the {@link SoapMessageDispatcher}
60-
* subclass is used. <ul> <li>It can use any {@link EndpointMapping} implementation - whether standard, or provided as
58+
* subclass is used.
59+
* <ul>
60+
* <li>It can use any {@link EndpointMapping} implementation - whether standard, or provided as
6161
* part of an application - to control the routing of request messages to endpoint objects. Endpoint mappings can be
62-
* registered using the <code>endpointMappings</code> property.</li> <li>It can use any {@link EndpointAdapter}; this
63-
* allows one to use any endpoint interface or form. Defaults to the {@link MessageEndpointAdapter} and {@link
64-
* PayloadEndpointAdapter}, for {@link MessageEndpoint} and {@link PayloadEndpoint}, respectively, and the {@link
65-
* MessageMethodEndpointAdapter} and {@link PayloadMethodEndpointAdapter}. Additional endpoint adapters can be added
66-
* through the <code>endpointAdapters</code> property.</li> <li>Its exception resolution strategy can be specified via a
62+
* registered using the {@link #setEndpointMappings(List) endpointMappings} property.</li>
63+
* <li>It can use any {@link EndpointAdapter}; this allows one to use any endpoint interface or form. Defaults to
64+
* the {@link MessageEndpointAdapter} and {@link PayloadEndpointAdapter}, for {@link MessageEndpoint} and
65+
* {@link PayloadEndpoint}, respectively, and the
66+
* {@link org.springframework.ws.server.endpoint.adapter.MessageMethodEndpointAdapter MessageMethodEndpointAdapter} and
67+
* {@link org.springframework.ws.server.endpoint.adapter.PayloadMethodEndpointAdapter PayloadMethodEndpointAdapter}.
68+
* Additional endpoint adapters can be added through the {@link #setEndpointAdapters(List) endpointAdapters} property.</li>
69+
* <li>Its exception resolution strategy can be specified via a
6770
* {@link EndpointExceptionResolver}, for example mapping certain exceptions to SOAP Faults. Default is none. Additional
68-
* exception resolvers can be added through the <code>endpointExceptionResolvers</code> property.</li> </ul>
71+
* exception resolvers can be added through the {@link #setEndpointExceptionResolvers(List) endpointExceptionResolvers}
72+
* property.</li>
73+
* </ul>
6974
*
7075
* @author Arjen Poutsma
7176
* @see EndpointMapping
@@ -221,6 +226,7 @@ protected final void dispatch(MessageContext messageContext) throws Exception {
221226
interceptorIndex = i;
222227
if (!interceptor.handleRequest(messageContext, mappedEndpoint.getEndpoint())) {
223228
triggerHandleResponse(mappedEndpoint, interceptorIndex, messageContext);
229+
triggerAfterCompletion(mappedEndpoint, interceptorIndex, messageContext, null);
224230
return;
225231
}
226232
}
@@ -231,6 +237,7 @@ protected final void dispatch(MessageContext messageContext) throws Exception {
231237

232238
// Apply handleResponse methods of registered interceptors
233239
triggerHandleResponse(mappedEndpoint, interceptorIndex, messageContext);
240+
triggerAfterCompletion(mappedEndpoint, interceptorIndex, messageContext, null);
234241
}
235242
catch (NoEndpointFoundException ex) {
236243
// No triggering of interceptors if no endpoint is found
@@ -243,6 +250,7 @@ protected final void dispatch(MessageContext messageContext) throws Exception {
243250
Object endpoint = mappedEndpoint != null ? mappedEndpoint.getEndpoint() : null;
244251
processEndpointException(messageContext, endpoint, ex);
245252
triggerHandleResponse(mappedEndpoint, interceptorIndex, messageContext);
253+
triggerAfterCompletion(mappedEndpoint, interceptorIndex, messageContext, ex);
246254
}
247255
}
248256

@@ -363,7 +371,41 @@ private void triggerHandleResponse(EndpointInvocationChain mappedEndpoint,
363371
}
364372

365373
/**
366-
* Initialize the <code>EndpointAdapters</code> used by this class. If no adapter beans are explictely set by using
374+
* Trigger afterCompletion callbacks on the mapped EndpointInterceptors.
375+
* Will just invoke afterCompletion for all interceptors whose handleRequest invocation
376+
* has successfully completed and returned true, in addition to the last interceptor who
377+
* returned <code>false</code>.
378+
*
379+
* @param mappedEndpoint the mapped EndpointInvocationChain
380+
* @param interceptorIndex index of last interceptor that successfully completed
381+
* @param ex Exception thrown on handler execution, or <code>null</code> if none
382+
* @see EndpointInterceptor#afterCompletion
383+
*/
384+
private void triggerAfterCompletion(EndpointInvocationChain mappedEndpoint,
385+
int interceptorIndex,
386+
MessageContext messageContext,
387+
Exception ex) throws Exception {
388+
389+
// Apply afterCompletion methods of registered interceptors.
390+
if (mappedEndpoint != null) {
391+
EndpointInterceptor[] interceptors = mappedEndpoint.getInterceptors();
392+
if (interceptors != null) {
393+
for (int i = interceptorIndex; i >= 0; i--) {
394+
EndpointInterceptor interceptor = interceptors[i];
395+
try {
396+
interceptor.afterCompletion(messageContext, mappedEndpoint.getEndpoint(), ex);
397+
}
398+
catch (Throwable ex2) {
399+
logger.error("EndpointInterceptor.afterCompletion threw exception", ex2);
400+
}
401+
}
402+
}
403+
}
404+
}
405+
406+
407+
/**
408+
* Initialize the <code>EndpointAdapters</code> used by this class. If no adapter beans are explicitly set by using
367409
* the <code>endpointAdapters</code> property, we use the default strategies.
368410
*
369411
* @see #setEndpointAdapters(java.util.List)

core/src/main/java/org/springframework/ws/server/endpoint/AbstractLoggingInterceptor.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2006 the original author or authors.
2+
* Copyright 2005-2011 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -24,14 +24,14 @@
2424
import javax.xml.transform.TransformerException;
2525
import javax.xml.transform.stream.StreamResult;
2626

27-
import org.apache.commons.logging.Log;
28-
import org.apache.commons.logging.LogFactory;
29-
3027
import org.springframework.ws.WebServiceMessage;
3128
import org.springframework.ws.context.MessageContext;
3229
import org.springframework.ws.server.EndpointInterceptor;
3330
import org.springframework.xml.transform.TransformerObjectSupport;
3431

32+
import org.apache.commons.logging.Log;
33+
import org.apache.commons.logging.LogFactory;
34+
3535
/**
3636
* Abstract base class for <code>EndpointInterceptor</code> instances that log a part of a
3737
* <code>WebServiceMessage</code>. By default, both request and response messages are logged, but this behaviour can be
@@ -77,7 +77,7 @@ public void setLoggerName(String loggerName) {
7777
}
7878

7979
/**
80-
* Logs the request message payload. Logging only ocurs if <code>logRequest</code> is set to <code>true</code>,
80+
* Logs the request message payload. Logging only occurs if <code>logRequest</code> is set to <code>true</code>,
8181
* which is the default.
8282
*
8383
* @param messageContext the message context
@@ -92,7 +92,7 @@ public final boolean handleRequest(MessageContext messageContext, Object endpoin
9292
}
9393

9494
/**
95-
* Logs the response message payload. Logging only ocurs if <code>logResponse</code> is set to <code>true</code>,
95+
* Logs the response message payload. Logging only occurs if <code>logResponse</code> is set to <code>true</code>,
9696
* which is the default.
9797
*
9898
* @param messageContext the message context
@@ -111,6 +111,10 @@ public boolean handleFault(MessageContext messageContext, Object endpoint) throw
111111
return true;
112112
}
113113

114+
/** Does nothing by default*/
115+
public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) {
116+
}
117+
114118
/**
115119
* Determine whether the {@link #logger} field is enabled.
116120
* <p/>
@@ -152,7 +156,7 @@ protected void logMessageSource(String logMessage, Source source) throws Transfo
152156
* Logs the given string message.
153157
* <p/>
154158
* By default, this method uses a "debug" level of logging. Subclasses can override this method to change the level
155-
* of loging used by the logger.
159+
* of logging used by the logger.
156160
*
157161
* @param message the message
158162
*/

core/src/main/java/org/springframework/ws/server/endpoint/interceptor/AbstractValidatingInterceptor.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@
2020
import javax.xml.transform.Source;
2121
import javax.xml.transform.TransformerException;
2222

23-
import org.xml.sax.SAXException;
24-
import org.xml.sax.SAXParseException;
25-
2623
import org.springframework.beans.factory.InitializingBean;
2724
import org.springframework.core.io.Resource;
2825
import org.springframework.util.Assert;
@@ -39,6 +36,9 @@
3936
import org.springframework.xml.xsd.XsdSchema;
4037
import org.springframework.xml.xsd.XsdSchemaCollection;
4138

39+
import org.xml.sax.SAXException;
40+
import org.xml.sax.SAXParseException;
41+
4242
/**
4343
* Abstract base class for <code>EndpointInterceptor</code> implementations that validate part of the message using a
4444
* schema. The exact message part is determined by the <code>getValidationRequestSource</code> and
@@ -245,6 +245,10 @@ public boolean handleFault(MessageContext messageContext, Object endpoint) throw
245245
return true;
246246
}
247247

248+
/** Does nothing by default.*/
249+
public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) {
250+
}
251+
248252
/**
249253
* Abstract template method that returns the part of the request message that is to be validated.
250254
*

core/src/main/java/org/springframework/ws/server/endpoint/interceptor/EndpointInterceptorAdapter.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2005 the original author or authors.
2+
* Copyright 2005-2011 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -16,10 +16,11 @@
1616

1717
package org.springframework.ws.server.endpoint.interceptor;
1818

19-
import org.apache.commons.logging.Log;
20-
import org.apache.commons.logging.LogFactory;
2119
import org.springframework.ws.context.MessageContext;
2220
import org.springframework.ws.server.EndpointInterceptor;
21+
22+
import org.apache.commons.logging.Log;
23+
import org.apache.commons.logging.LogFactory;
2324
import org.w3c.dom.Element;
2425

2526
/**
@@ -65,4 +66,10 @@ public boolean handleResponse(MessageContext messageContext, Object endpoint) th
6566
public boolean handleFault(MessageContext messageContext, Object endpoint) {
6667
return true;
6768
}
69+
70+
/**
71+
* Does nothing by default.
72+
*/
73+
public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) {
74+
}
6875
}

core/src/main/java/org/springframework/ws/server/endpoint/interceptor/PayloadTransformingInterceptor.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2006 the original author or authors.
2+
* Copyright 2005-2011 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -26,11 +26,6 @@
2626
import javax.xml.transform.stream.StreamResult;
2727
import javax.xml.transform.stream.StreamSource;
2828

29-
import org.apache.commons.logging.Log;
30-
import org.apache.commons.logging.LogFactory;
31-
import org.xml.sax.XMLReader;
32-
import org.xml.sax.helpers.XMLReaderFactory;
33-
3429
import org.springframework.beans.factory.InitializingBean;
3530
import org.springframework.core.io.Resource;
3631
import org.springframework.util.Assert;
@@ -40,6 +35,11 @@
4035
import org.springframework.xml.transform.ResourceSource;
4136
import org.springframework.xml.transform.TransformerObjectSupport;
4237

38+
import org.apache.commons.logging.Log;
39+
import org.apache.commons.logging.LogFactory;
40+
import org.xml.sax.XMLReader;
41+
import org.xml.sax.helpers.XMLReaderFactory;
42+
4343
/**
4444
* Interceptor that transforms the payload of <code>WebServiceMessage</code>s using XSLT stylesheet. Allows for seperate
4545
* stylesheets for request and response. This interceptor is especially useful when supporting with multiple version of
@@ -125,6 +125,10 @@ public boolean handleFault(MessageContext messageContext, Object endpoint) throw
125125
return true;
126126
}
127127

128+
/** Does nothing by default.*/
129+
public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) {
130+
}
131+
128132
public void afterPropertiesSet() throws Exception {
129133
if (requestXslt == null && responseXslt == null) {
130134
throw new IllegalArgumentException("Setting either 'requestXslt' or 'responseXslt' is required");

core/src/main/java/org/springframework/ws/soap/addressing/server/AddressingEndpointInterceptor.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2007 the original author or authors.
2+
* Copyright 2005-2011 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -19,9 +19,6 @@
1919
import java.io.IOException;
2020
import java.net.URI;
2121

22-
import org.apache.commons.logging.Log;
23-
import org.apache.commons.logging.LogFactory;
24-
2522
import org.springframework.util.Assert;
2623
import org.springframework.ws.context.MessageContext;
2724
import org.springframework.ws.soap.SoapHeaderElement;
@@ -34,6 +31,9 @@
3431
import org.springframework.ws.transport.WebServiceConnection;
3532
import org.springframework.ws.transport.WebServiceMessageSender;
3633

34+
import org.apache.commons.logging.Log;
35+
import org.apache.commons.logging.LogFactory;
36+
3737
/**
3838
* {@link SoapEndpointInterceptor} implementation that deals with WS-Addressing headers. Stateful, and instatiated by
3939
* the {@link AbstractAddressingEndpointMapping}.
@@ -178,6 +178,9 @@ private URI getMessageId(SoapMessage response) {
178178
return responseMessageId;
179179
}
180180

181+
public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) {
182+
}
183+
181184
public boolean understands(SoapHeaderElement header) {
182185
return version.understands(header);
183186
}

0 commit comments

Comments
 (0)