Skip to content

Commit 915cd94

Browse files
committed
Working on SWS-207
1 parent bae5ff8 commit 915cd94

File tree

75 files changed

+3021
-88
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+3021
-88
lines changed

parent/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -569,9 +569,9 @@
569569
<version>1.3.0</version>
570570
</dependency>
571571
<dependency>
572-
<groupId>wss4j</groupId>
572+
<groupId>org.apache.ws.security</groupId>
573573
<artifactId>wss4j</artifactId>
574-
<version>1.5.1</version>
574+
<version>1.5.4</version>
575575
</dependency>
576576
<dependency>
577577
<groupId>org.acegisecurity</groupId>

pom.xml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<url>http://static.springframework.org/spring-ws/site/index.html</url>
1616
<issueManagement>
1717
<system>JIRA</system>
18-
<url>http://opensource2.atlassian.com/projects/spring/browse/SWS/</url>
18+
<url>http://jira.springframework.org/browse/SWS</url>
1919
</issueManagement>
2020
<ciManagement>
2121
<system>bamboo</system>
@@ -49,6 +49,9 @@
4949
<contributor>
5050
<name>Rick Evans</name>
5151
</contributor>
52+
<contributor>
53+
<name>Tareq Abed Rabbo</name>
54+
</contributor>
5255
</contributors>
5356
<organization>
5457
<name>The Spring Web Services Framework</name>

security/pom.xml

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@
2222
<name>Spring External Dependencies Repository</name>
2323
<url>https://springframework.svn.sourceforge.net/svnroot/springframework/repos/repo-ext/</url>
2424
</repository>
25+
<repository>
26+
<id>wso2</id>
27+
<name>WSO2 Repository</name>
28+
<url>http://dist.wso2.org/maven2/</url>
29+
</repository>
2530
</repositories>
2631
<profiles>
2732
<profile>
@@ -103,7 +108,17 @@
103108
<artifactId>saaj-impl</artifactId>
104109
<scope>provided</scope>
105110
</dependency>
106-
<!-- WS-Security dependencies -->
111+
<dependency>
112+
<groupId>org.apache.ws.commons.axiom</groupId>
113+
<artifactId>axiom-api</artifactId>
114+
<optional>true</optional>
115+
</dependency>
116+
<dependency>
117+
<groupId>org.apache.ws.commons.axiom</groupId>
118+
<artifactId>axiom-impl</artifactId>
119+
<optional>true</optional>
120+
</dependency>
121+
<!-- XWSS dependencies -->
107122
<dependency>
108123
<groupId>com.sun.xml.wss</groupId>
109124
<artifactId>xws-security</artifactId>
@@ -112,6 +127,12 @@
112127
<groupId>xml-security</groupId>
113128
<artifactId>xmlsec</artifactId>
114129
</dependency>
130+
<!-- WSS4J dependencies -->
131+
<dependency>
132+
<groupId>org.apache.ws.security</groupId>
133+
<artifactId>wss4j</artifactId>
134+
</dependency>
135+
<!-- Acegi depdencies -->
115136
<dependency>
116137
<groupId>org.acegisecurity</groupId>
117138
<artifactId>acegi-security</artifactId>

security/src/main/java/org/springframework/ws/soap/security/AbstractWsSecurityInterceptor.java

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public abstract class AbstractWsSecurityInterceptor implements SoapEndpointInter
5252
/** Logger available to subclasses. */
5353
protected final Log logger = LogFactory.getLog(getClass());
5454

55-
private static final QName WS_SECURITY_NAME =
55+
protected static final QName WS_SECURITY_NAME =
5656
new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security");
5757

5858
private boolean secureResponse = true;
@@ -88,20 +88,20 @@ public void setValidateResponse(boolean validateResponse) {
8888
*/
8989

9090
/**
91-
* Validates a server-side incoming request. Delegates to {@link #validateMessage(SoapMessage)} if the {@link
92-
* #setValidateRequest(boolean) validateRequest} property is <code>true</code>.
91+
* Validates a server-side incoming request. Delegates to {@link #validateMessage(org.springframework.ws.soap.SoapMessage,org.springframework.ws.context.MessageContext)}
92+
* if the {@link #setValidateRequest(boolean) validateRequest} property is <code>true</code>.
9393
*
9494
* @param messageContext the message context, containing the request to be validated
9595
* @param endpoint chosen endpoint to invoke
9696
* @return <code>true</code> if the request was valid; <code>false</code> otherwise.
9797
* @throws Exception in case of errors
98-
* @see #validateMessage(SoapMessage)
98+
* @see #validateMessage(org.springframework.ws.soap.SoapMessage,org.springframework.ws.context.MessageContext)
9999
*/
100100
public final boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {
101101
if (validateRequest) {
102102
Assert.isInstanceOf(SoapMessage.class, messageContext.getRequest());
103103
try {
104-
validateMessage((SoapMessage) messageContext.getRequest());
104+
validateMessage((SoapMessage) messageContext.getRequest(), messageContext);
105105
return true;
106106
}
107107
catch (WsSecurityValidationException ex) {
@@ -117,21 +117,21 @@ public final boolean handleRequest(MessageContext messageContext, Object endpoin
117117
}
118118

119119
/**
120-
* Secures a server-side outgoing response. Delegates to {@link #secureMessage(SoapMessage)} if the {@link
121-
* #setSecureResponse(boolean) secureResponse} property is <code>true</code>.
120+
* Secures a server-side outgoing response. Delegates to {@link #secureMessage(org.springframework.ws.soap.SoapMessage,org.springframework.ws.context.MessageContext)}
121+
* if the {@link #setSecureResponse(boolean) secureResponse} property is <code>true</code>.
122122
*
123123
* @param messageContext the message context, containing the response to be secured
124124
* @param endpoint chosen endpoint to invoke
125125
* @return <code>true</code> if the response was secured; <code>false</code> otherwise.
126126
* @throws Exception in case of errors
127-
* @see #secureMessage(SoapMessage)
127+
* @see #secureMessage(org.springframework.ws.soap.SoapMessage,org.springframework.ws.context.MessageContext)
128128
*/
129129
public final boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {
130130
if (secureResponse) {
131131
Assert.isTrue(messageContext.hasResponse(), "MessageContext contains no response");
132132
Assert.isInstanceOf(SoapMessage.class, messageContext.getResponse());
133133
try {
134-
secureMessage((SoapMessage) messageContext.getResponse());
134+
secureMessage((SoapMessage) messageContext.getResponse(), messageContext);
135135
return true;
136136
}
137137
catch (WsSecuritySecurementException ex) {
@@ -160,19 +160,19 @@ public boolean understands(SoapHeaderElement headerElement) {
160160
*/
161161

162162
/**
163-
* Secures a client-side outgoing request. Delegates to {@link #secureMessage(SoapMessage)} if the {@link
164-
* #setSecureRequest(boolean) secureRequest} property is <code>true</code>.
163+
* Secures a client-side outgoing request. Delegates to {@link #secureMessage(org.springframework.ws.soap.SoapMessage,org.springframework.ws.context.MessageContext)}
164+
* if the {@link #setSecureRequest(boolean) secureRequest} property is <code>true</code>.
165165
*
166166
* @param messageContext the message context, containing the request to be secured
167167
* @return <code>true</code> if the response was secured; <code>false</code> otherwise.
168168
* @throws Exception in case of errors
169-
* @see #secureMessage(SoapMessage)
169+
* @see #secureMessage(org.springframework.ws.soap.SoapMessage,org.springframework.ws.context.MessageContext)
170170
*/
171171
public final boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {
172172
if (secureRequest) {
173173
Assert.isInstanceOf(SoapMessage.class, messageContext.getRequest());
174174
try {
175-
secureMessage((SoapMessage) messageContext.getRequest());
175+
secureMessage((SoapMessage) messageContext.getRequest(), messageContext);
176176
return true;
177177
}
178178
catch (WsSecuritySecurementException ex) {
@@ -188,20 +188,20 @@ public final boolean handleRequest(MessageContext messageContext) throws WebServ
188188
}
189189

190190
/**
191-
* Validates a client-side incoming response. Delegates to {@link #validateMessage(SoapMessage)} if the {@link
192-
* #setValidateResponse(boolean) validateResponse} property is <code>true</code>.
191+
* Validates a client-side incoming response. Delegates to {@link #validateMessage(org.springframework.ws.soap.SoapMessage,org.springframework.ws.context.MessageContext)}
192+
* if the {@link #setValidateResponse(boolean) validateResponse} property is <code>true</code>.
193193
*
194194
* @param messageContext the message context, containing the response to be validated
195195
* @return <code>true</code> if the request was valid; <code>false</code> otherwise.
196196
* @throws Exception in case of errors
197-
* @see #validateMessage(SoapMessage)
197+
* @see #validateMessage(org.springframework.ws.soap.SoapMessage,org.springframework.ws.context.MessageContext)
198198
*/
199199
public final boolean handleResponse(MessageContext messageContext) throws WebServiceClientException {
200200
if (validateResponse) {
201201
Assert.isTrue(messageContext.hasResponse(), "MessageContext contains no response");
202202
Assert.isInstanceOf(SoapMessage.class, messageContext.getResponse());
203203
try {
204-
validateMessage((SoapMessage) messageContext.getResponse());
204+
validateMessage((SoapMessage) messageContext.getResponse(), messageContext);
205205
return true;
206206
}
207207
catch (WsSecurityValidationException ex) {
@@ -284,7 +284,8 @@ protected boolean handleFaultException(WsSecurityFaultException ex, MessageConte
284284
* @param soapMessage the soap message to validate
285285
* @throws WsSecurityValidationException in case of validation errors
286286
*/
287-
protected abstract void validateMessage(SoapMessage soapMessage) throws WsSecurityValidationException;
287+
protected abstract void validateMessage(SoapMessage soapMessage, MessageContext messageContext)
288+
throws WsSecurityValidationException;
288289

289290
/**
290291
* Abstract template method. Subclasses are required to secure the response contained in the given {@link
@@ -293,5 +294,6 @@ protected boolean handleFaultException(WsSecurityFaultException ex, MessageConte
293294
* @param soapMessage the soap message to secure
294295
* @throws WsSecuritySecurementException in case of securement errors
295296
*/
296-
protected abstract void secureMessage(SoapMessage soapMessage) throws WsSecuritySecurementException;
297+
protected abstract void secureMessage(SoapMessage soapMessage, MessageContext messageContext)
298+
throws WsSecuritySecurementException;
297299
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.ws.soap.security.xwss.callback;
17+
package org.springframework.ws.soap.security.callback;
1818

1919
import java.io.IOException;
2020
import javax.security.auth.callback.Callback;
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
/*
2+
* Copyright 2006 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.callback;
18+
19+
import java.io.IOException;
20+
import java.security.cert.X509Certificate;
21+
import javax.security.auth.callback.Callback;
22+
import javax.security.auth.callback.CallbackHandler;
23+
import javax.security.auth.callback.UnsupportedCallbackException;
24+
25+
import com.sun.xml.wss.impl.callback.CertificateValidationCallback;
26+
import com.sun.xml.wss.impl.callback.PasswordValidationCallback;
27+
import com.sun.xml.wss.impl.callback.TimestampValidationCallback;
28+
29+
/**
30+
* Represents a chain of <code>CallbackHandler</code>s. For each callback, each of the handlers is called in term. If a
31+
* handler throws a <code>UnsupportedCallbackException</code>, the next handler is tried.
32+
*
33+
* @author Arjen Poutsma
34+
* @since 1.0.0
35+
*/
36+
public class CallbackHandlerChain extends AbstractCallbackHandler {
37+
38+
private CallbackHandler[] callbackHandlers;
39+
40+
public CallbackHandlerChain(CallbackHandler[] callbackHandlers) {
41+
this.callbackHandlers = callbackHandlers;
42+
}
43+
44+
public void setCallbackHandlers(CallbackHandler[] callbackHandlers) {
45+
this.callbackHandlers = callbackHandlers;
46+
}
47+
48+
protected void handleInternal(Callback callback) throws IOException, UnsupportedCallbackException {
49+
if (callback instanceof CertificateValidationCallback) {
50+
handleCertificateValidationCallback((CertificateValidationCallback) callback);
51+
}
52+
else if (callback instanceof PasswordValidationCallback) {
53+
handlePasswordValidationCallback((PasswordValidationCallback) callback);
54+
}
55+
else if (callback instanceof TimestampValidationCallback) {
56+
handleTimestampValidationCallback((TimestampValidationCallback) callback);
57+
}
58+
else {
59+
boolean allUnsupported = true;
60+
for (int i = 0; i < callbackHandlers.length; i++) {
61+
CallbackHandler callbackHandler = callbackHandlers[i];
62+
try {
63+
callbackHandler.handle(new Callback[]{callback});
64+
allUnsupported = false;
65+
}
66+
catch (UnsupportedCallbackException ex) {
67+
// if an UnsupportedCallbackException occurs, go to the next handler
68+
}
69+
}
70+
if (allUnsupported) {
71+
throw new UnsupportedCallbackException(callback);
72+
}
73+
}
74+
}
75+
76+
private void handleCertificateValidationCallback(CertificateValidationCallback callback) {
77+
callback.setValidator(new CertificateValidatorChain(callback));
78+
}
79+
80+
private void handlePasswordValidationCallback(PasswordValidationCallback callback) {
81+
callback.setValidator(new PasswordValidatorChain(callback));
82+
}
83+
84+
private void handleTimestampValidationCallback(TimestampValidationCallback callback) {
85+
callback.setValidator(new TimestampValidatorChain(callback));
86+
}
87+
88+
private class TimestampValidatorChain implements TimestampValidationCallback.TimestampValidator {
89+
90+
private TimestampValidationCallback callback;
91+
92+
private TimestampValidatorChain(TimestampValidationCallback callback) {
93+
this.callback = callback;
94+
}
95+
96+
public void validate(TimestampValidationCallback.Request request)
97+
throws TimestampValidationCallback.TimestampValidationException {
98+
for (int i = 0; i < callbackHandlers.length; i++) {
99+
CallbackHandler callbackHandler = callbackHandlers[i];
100+
try {
101+
callbackHandler.handle(new Callback[]{callback});
102+
callback.getResult();
103+
}
104+
catch (IOException e) {
105+
throw new TimestampValidationCallback.TimestampValidationException(e);
106+
}
107+
catch (UnsupportedCallbackException e) {
108+
// ignore
109+
}
110+
}
111+
}
112+
}
113+
114+
private class PasswordValidatorChain implements PasswordValidationCallback.PasswordValidator {
115+
116+
private PasswordValidationCallback callback;
117+
118+
private PasswordValidatorChain(PasswordValidationCallback callback) {
119+
this.callback = callback;
120+
}
121+
122+
public boolean validate(PasswordValidationCallback.Request request)
123+
throws PasswordValidationCallback.PasswordValidationException {
124+
boolean allUnsupported = true;
125+
for (int i = 0; i < callbackHandlers.length; i++) {
126+
CallbackHandler callbackHandler = callbackHandlers[i];
127+
try {
128+
callbackHandler.handle(new Callback[]{callback});
129+
allUnsupported = false;
130+
if (!callback.getResult()) {
131+
return false;
132+
}
133+
}
134+
catch (IOException e) {
135+
throw new PasswordValidationCallback.PasswordValidationException(e);
136+
}
137+
catch (UnsupportedCallbackException e) {
138+
// ignore
139+
}
140+
}
141+
return !allUnsupported;
142+
}
143+
}
144+
145+
private class CertificateValidatorChain implements CertificateValidationCallback.CertificateValidator {
146+
147+
private CertificateValidationCallback callback;
148+
149+
private CertificateValidatorChain(CertificateValidationCallback callback) {
150+
this.callback = callback;
151+
}
152+
153+
public boolean validate(X509Certificate certificate)
154+
throws CertificateValidationCallback.CertificateValidationException {
155+
boolean allUnsupported = true;
156+
for (int i = 0; i < callbackHandlers.length; i++) {
157+
CallbackHandler callbackHandler = callbackHandlers[i];
158+
try {
159+
callbackHandler.handle(new Callback[]{callback});
160+
allUnsupported = false;
161+
if (!callback.getResult()) {
162+
return false;
163+
}
164+
}
165+
catch (IOException e) {
166+
throw new CertificateValidationCallback.CertificateValidationException(e);
167+
}
168+
catch (UnsupportedCallbackException e) {
169+
// ignore
170+
}
171+
}
172+
return !allUnsupported;
173+
}
174+
}
175+
}

0 commit comments

Comments
 (0)