Skip to content

Commit 95ac668

Browse files
committed
SWS-708 - PayloadValidatingInterceptor errors not clearing SecurityContextHolder
1 parent da9e377 commit 95ac668

File tree

16 files changed

+460
-67
lines changed

16 files changed

+460
-67
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: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2005-2010 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,
@@ -221,6 +221,7 @@ protected final void dispatch(MessageContext messageContext) throws Exception {
221221
interceptorIndex = i;
222222
if (!interceptor.handleRequest(messageContext, mappedEndpoint.getEndpoint())) {
223223
triggerHandleResponse(mappedEndpoint, interceptorIndex, messageContext);
224+
triggerAfterCompletion(mappedEndpoint, interceptorIndex, messageContext, null);
224225
return;
225226
}
226227
}
@@ -231,6 +232,7 @@ protected final void dispatch(MessageContext messageContext) throws Exception {
231232

232233
// Apply handleResponse methods of registered interceptors
233234
triggerHandleResponse(mappedEndpoint, interceptorIndex, messageContext);
235+
triggerAfterCompletion(mappedEndpoint, interceptorIndex, messageContext, null);
234236
}
235237
catch (NoEndpointFoundException ex) {
236238
// No triggering of interceptors if no endpoint is found
@@ -243,6 +245,7 @@ protected final void dispatch(MessageContext messageContext) throws Exception {
243245
Object endpoint = mappedEndpoint != null ? mappedEndpoint.getEndpoint() : null;
244246
processEndpointException(messageContext, endpoint, ex);
245247
triggerHandleResponse(mappedEndpoint, interceptorIndex, messageContext);
248+
triggerAfterCompletion(mappedEndpoint, interceptorIndex, messageContext, ex);
246249
}
247250
}
248251

@@ -359,6 +362,40 @@ private void triggerHandleResponse(EndpointInvocationChain mappedEndpoint,
359362
}
360363
}
361364

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

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2005-2010 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,
@@ -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/>

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,10 @@ public boolean handleFault(MessageContext messageContext, Object endpoint) throw
257257
return true;
258258
}
259259

260+
/** Does nothing by default.*/
261+
public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) {
262+
}
263+
260264
/**
261265
* Abstract template method that returns the part of the request message that is to be validated.
262266
*

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,8 @@ public boolean handleResponse(MessageContext messageContext, Object endpoint) th
8585
public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {
8686
return getDelegate().handleFault(messageContext, endpoint);
8787
}
88+
89+
public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) {
90+
getDelegate().afterCompletion(messageContext, endpoint, ex);
91+
}
8892
}

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: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2005-2010 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,
@@ -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
}

core/src/test/java/org/springframework/ws/server/MessageDispatcherTest.java

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2005-2010 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,
@@ -171,8 +171,8 @@ public void testNormalFlow() throws Exception {
171171
EndpointMapping mappingMock = createMock(EndpointMapping.class);
172172
dispatcher.setEndpointMappings(Collections.singletonList(mappingMock));
173173

174-
EndpointInterceptor interceptorMock1 = createMock("interceptor1", EndpointInterceptor.class);
175-
EndpointInterceptor interceptorMock2 = createMock("interceptor2", EndpointInterceptor.class);
174+
EndpointInterceptor interceptorMock1 = createStrictMock("interceptor1", EndpointInterceptor.class);
175+
EndpointInterceptor interceptorMock2 = createStrictMock("interceptor2", EndpointInterceptor.class);
176176

177177
expect(interceptorMock1.handleRequest(messageContext, endpoint)).andReturn(true);
178178
expect(interceptorMock2.handleRequest(messageContext, endpoint)).andReturn(true);
@@ -182,6 +182,9 @@ public void testNormalFlow() throws Exception {
182182
expect(interceptorMock2.handleResponse(messageContext, endpoint)).andReturn(true);
183183
expect(interceptorMock1.handleResponse(messageContext, endpoint)).andReturn(true);
184184

185+
interceptorMock2.afterCompletion(messageContext, endpoint, null);
186+
interceptorMock1.afterCompletion(messageContext, endpoint, null);
187+
185188
EndpointInvocationChain chain =
186189
new EndpointInvocationChain(endpoint, new EndpointInterceptor[]{interceptorMock1, interceptorMock2});
187190

@@ -208,15 +211,17 @@ public void testFlowNoResponse() throws Exception {
208211
EndpointMapping mappingMock = createMock(EndpointMapping.class);
209212
dispatcher.setEndpointMappings(Collections.singletonList(mappingMock));
210213

211-
EndpointInterceptor interceptorMock1 = createMock("interceptor1", EndpointInterceptor.class);
212-
EndpointInterceptor interceptorMock2 = createMock("interceptor2", EndpointInterceptor.class);
214+
EndpointInterceptor interceptorMock1 = createStrictMock("interceptor1", EndpointInterceptor.class);
215+
EndpointInterceptor interceptorMock2 = createStrictMock("interceptor2", EndpointInterceptor.class);
213216

214217
EndpointInvocationChain chain =
215218
new EndpointInvocationChain(endpoint, new EndpointInterceptor[]{interceptorMock1, interceptorMock2});
216219
expect(mappingMock.getEndpoint(messageContext)).andReturn(chain);
217220

218221
expect(interceptorMock1.handleRequest(messageContext, endpoint)).andReturn(true);
219222
expect(interceptorMock2.handleRequest(messageContext, endpoint)).andReturn(true);
223+
interceptorMock2.afterCompletion(messageContext, endpoint, null);
224+
interceptorMock1.afterCompletion(messageContext, endpoint, null);
220225

221226
adapterMock.invoke(messageContext, endpoint);
222227

@@ -235,13 +240,14 @@ public void testInterceptedRequestFlow() throws Exception {
235240
EndpointMapping mappingMock = createMock(EndpointMapping.class);
236241
dispatcher.setEndpointMappings(Collections.singletonList(mappingMock));
237242

238-
EndpointInterceptor interceptorMock1 = createMock("interceptor1", EndpointInterceptor.class);
239-
EndpointInterceptor interceptorMock2 = createMock("interceptor2", EndpointInterceptor.class);
243+
EndpointInterceptor interceptorMock1 = createStrictMock("interceptor1", EndpointInterceptor.class);
244+
EndpointInterceptor interceptorMock2 = createStrictMock("interceptor2", EndpointInterceptor.class);
240245

241246
Object endpoint = new Object();
242247

243248
expect(interceptorMock1.handleRequest(messageContext, endpoint)).andReturn(false);
244249
expect(interceptorMock1.handleResponse(messageContext, endpoint)).andReturn(true);
250+
interceptorMock1.afterCompletion(messageContext, endpoint, null);
245251

246252
EndpointInvocationChain chain =
247253
new EndpointInvocationChain(endpoint, new EndpointInterceptor[]{interceptorMock1, interceptorMock2});
@@ -267,13 +273,15 @@ public void testInterceptedResponseFlow() throws Exception {
267273
EndpointMapping mappingMock = createMock(EndpointMapping.class);
268274
dispatcher.setEndpointMappings(Collections.singletonList(mappingMock));
269275

270-
EndpointInterceptor interceptorMock1 = createMock("interceptor1", EndpointInterceptor.class);
271-
EndpointInterceptor interceptorMock2 = createMock("interceptor2", EndpointInterceptor.class);
276+
EndpointInterceptor interceptorMock1 = createStrictMock("interceptor1", EndpointInterceptor.class);
277+
EndpointInterceptor interceptorMock2 = createStrictMock("interceptor2", EndpointInterceptor.class);
272278

273279
Object endpoint = new Object();
274280
expect(interceptorMock1.handleRequest(messageContext, endpoint)).andReturn(true);
275281
expect(interceptorMock2.handleRequest(messageContext, endpoint)).andReturn(false);
276282
expect(interceptorMock2.handleResponse(messageContext, endpoint)).andReturn(false);
283+
interceptorMock1.afterCompletion(messageContext, endpoint, null);
284+
interceptorMock2.afterCompletion(messageContext, endpoint, null);
277285

278286
EndpointInvocationChain chain =
279287
new EndpointInvocationChain(endpoint, new EndpointInterceptor[]{interceptorMock1, interceptorMock2});
@@ -290,7 +298,7 @@ public void testInterceptedResponseFlow() throws Exception {
290298

291299
verify(mappingMock, interceptorMock1, interceptorMock2, adapterMock, factoryMock);
292300
}
293-
301+
294302
@Test
295303
public void testFaultFlow() throws Exception {
296304
EndpointAdapter adapterMock = createMock(EndpointAdapter.class);
@@ -302,11 +310,12 @@ public void testFaultFlow() throws Exception {
302310
EndpointMapping mappingMock = createMock(EndpointMapping.class);
303311
dispatcher.setEndpointMappings(Collections.singletonList(mappingMock));
304312

305-
EndpointInterceptor interceptorMock = createMock(EndpointInterceptor.class);
313+
EndpointInterceptor interceptorMock = createStrictMock(EndpointInterceptor.class);
306314

307315
expect(interceptorMock.handleRequest(messageContext, endpoint)).andReturn(true);
308316
adapterMock.invoke(messageContext, endpoint);
309317
expect(interceptorMock.handleFault(messageContext, endpoint)).andReturn(true);
318+
interceptorMock.afterCompletion(messageContext, endpoint, null);
310319

311320
EndpointInvocationChain chain =
312321
new EndpointInvocationChain(endpoint, new EndpointInterceptor[]{interceptorMock});

parent/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@
352352
<dependency>
353353
<groupId>org.apache.ws.commons.schema</groupId>
354354
<artifactId>XmlSchema</artifactId>
355-
<version>1.4.3</version>
355+
<version>1.4.5</version>
356356
</dependency>
357357
<!-- O/X Mapping dependencies -->
358358
<!-- Castor -->

0 commit comments

Comments
 (0)