Moved Spring-WS to separate dir.
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.security.xwss;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import javax.xml.soap.MessageFactory;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.springframework.ws.soap.saaj.SaajSoapMessageContext;
|
||||
import org.springframework.ws.transport.TransportRequest;
|
||||
import org.springframework.ws.transport.TransportException;
|
||||
|
||||
public class XwsSecurityInterceptorTest extends TestCase {
|
||||
|
||||
private MessageFactory messageFactory;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
messageFactory = MessageFactory.newInstance();
|
||||
}
|
||||
|
||||
public void testhandleRequest() throws Exception {
|
||||
final SOAPMessage request = messageFactory.createMessage();
|
||||
final SOAPMessage validatedRequest = messageFactory.createMessage();
|
||||
XwsSecurityInterceptor interceptor = new XwsSecurityInterceptor() {
|
||||
protected SOAPMessage secureMessage(SOAPMessage message) throws XwsSecuritySecurementException {
|
||||
fail("secure not expected");
|
||||
return null;
|
||||
}
|
||||
|
||||
protected SOAPMessage validateMessage(SOAPMessage message) throws XwsSecurityValidationException {
|
||||
assertEquals("Invalid message", request, message);
|
||||
return validatedRequest;
|
||||
}
|
||||
|
||||
};
|
||||
SaajSoapMessageContext context =
|
||||
new SaajSoapMessageContext(request, new DummyTransportRequest(), messageFactory);
|
||||
interceptor.handleRequest(context, null);
|
||||
assertEquals("Invalid request", validatedRequest, context.getSaajRequest());
|
||||
}
|
||||
|
||||
public void testhandleResponse() throws Exception {
|
||||
final SOAPMessage response = messageFactory.createMessage();
|
||||
final SOAPMessage securedResponse = messageFactory.createMessage();
|
||||
XwsSecurityInterceptor interceptor = new XwsSecurityInterceptor() {
|
||||
protected SOAPMessage secureMessage(SOAPMessage message) throws XwsSecuritySecurementException {
|
||||
assertEquals("Invalid message", response, message);
|
||||
return securedResponse;
|
||||
}
|
||||
|
||||
protected SOAPMessage validateMessage(SOAPMessage message) throws XwsSecurityValidationException {
|
||||
fail("validate not expected");
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
SOAPMessage request = messageFactory.createMessage();
|
||||
SaajSoapMessageContext context =
|
||||
new SaajSoapMessageContext(request, new DummyTransportRequest(), messageFactory);
|
||||
context.setSaajResponse(response);
|
||||
interceptor.handleResponse(context, null);
|
||||
assertEquals("Invalid response", securedResponse, context.getSaajResponse());
|
||||
}
|
||||
|
||||
private static class DummyTransportRequest implements TransportRequest {
|
||||
|
||||
public Iterator getHeaderNames() {
|
||||
return Collections.EMPTY_LIST.iterator();
|
||||
}
|
||||
|
||||
public Iterator getHeaders(String name) {
|
||||
return Collections.EMPTY_LIST.iterator();
|
||||
}
|
||||
|
||||
public String getUrl() throws TransportException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright 2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.security.xwss;
|
||||
|
||||
import javax.security.auth.callback.Callback;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
|
||||
import com.sun.xml.wss.impl.callback.DecryptionKeyCallback;
|
||||
import com.sun.xml.wss.impl.callback.EncryptionKeyCallback;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.ws.soap.security.xwss.callback.AbstractCallbackHandler;
|
||||
|
||||
public class XwssMessageInterceptorEncryptTest extends XwssMessageInterceptorKeyStoreTestCase {
|
||||
|
||||
public void testEncryptDefaultCertificate() throws Exception {
|
||||
interceptor.setPolicyConfiguration(new ClassPathResource("encrypt-config.xml", getClass()));
|
||||
CallbackHandler handler = new AbstractCallbackHandler() {
|
||||
|
||||
protected void handleInternal(Callback callback) {
|
||||
if (callback instanceof EncryptionKeyCallback) {
|
||||
EncryptionKeyCallback keyCallback = (EncryptionKeyCallback) callback;
|
||||
if (keyCallback.getRequest() instanceof EncryptionKeyCallback.AliasX509CertificateRequest) {
|
||||
EncryptionKeyCallback.AliasX509CertificateRequest request =
|
||||
(EncryptionKeyCallback.AliasX509CertificateRequest) keyCallback.getRequest();
|
||||
assertEquals("Invalid alias", "", request.getAlias());
|
||||
request.setX509Certificate(certificate);
|
||||
}
|
||||
else {
|
||||
fail("Unexpected request");
|
||||
}
|
||||
}
|
||||
else {
|
||||
fail("Unexpected callback");
|
||||
}
|
||||
}
|
||||
};
|
||||
interceptor.setCallbackHandler(handler);
|
||||
interceptor.afterPropertiesSet();
|
||||
SOAPMessage message = loadSaajMessage("empty-soap.xml");
|
||||
SOAPMessage result = interceptor.secureMessage(message);
|
||||
assertNotNull("No result returned", result);
|
||||
assertXpathExists("BinarySecurityToken does not exist",
|
||||
"SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/wsse:BinarySecurityToken", result);
|
||||
assertXpathExists("Signature does not exist",
|
||||
"/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/xenc:EncryptedKey", result);
|
||||
}
|
||||
|
||||
public void testEncryptAlias() throws Exception {
|
||||
interceptor.setPolicyConfiguration(new ClassPathResource("encrypt-alias-config.xml", getClass()));
|
||||
CallbackHandler handler = new AbstractCallbackHandler() {
|
||||
|
||||
protected void handleInternal(Callback callback) {
|
||||
if (callback instanceof EncryptionKeyCallback) {
|
||||
EncryptionKeyCallback keyCallback = (EncryptionKeyCallback) callback;
|
||||
if (keyCallback.getRequest() instanceof EncryptionKeyCallback.AliasX509CertificateRequest) {
|
||||
EncryptionKeyCallback.AliasX509CertificateRequest request =
|
||||
(EncryptionKeyCallback.AliasX509CertificateRequest) keyCallback.getRequest();
|
||||
assertEquals("Invalid alias", "alias", request.getAlias());
|
||||
request.setX509Certificate(certificate);
|
||||
}
|
||||
else {
|
||||
fail("Unexpected request");
|
||||
}
|
||||
}
|
||||
else {
|
||||
fail("Unexpected callback");
|
||||
}
|
||||
}
|
||||
};
|
||||
interceptor.setCallbackHandler(handler);
|
||||
interceptor.afterPropertiesSet();
|
||||
SOAPMessage message = loadSaajMessage("empty-soap.xml");
|
||||
SOAPMessage result = interceptor.secureMessage(message);
|
||||
assertNotNull("No result returned", result);
|
||||
assertXpathExists("BinarySecurityToken does not exist",
|
||||
"SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/wsse:BinarySecurityToken", result);
|
||||
assertXpathExists("Signature does not exist",
|
||||
"/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/xenc:EncryptedKey", result);
|
||||
}
|
||||
|
||||
public void testDecrypt() throws Exception {
|
||||
interceptor.setPolicyConfiguration(new ClassPathResource("decrypt-config.xml", getClass()));
|
||||
CallbackHandler handler = new AbstractCallbackHandler() {
|
||||
|
||||
protected void handleInternal(Callback callback) {
|
||||
if (callback instanceof DecryptionKeyCallback) {
|
||||
DecryptionKeyCallback keyCallback = (DecryptionKeyCallback) callback;
|
||||
if (keyCallback.getRequest() instanceof DecryptionKeyCallback.X509CertificateBasedRequest) {
|
||||
DecryptionKeyCallback.X509CertificateBasedRequest request =
|
||||
(DecryptionKeyCallback.X509CertificateBasedRequest) keyCallback.getRequest();
|
||||
assertEquals("Invalid certificate", certificate, request.getX509Certificate());
|
||||
request.setPrivateKey(privateKey);
|
||||
}
|
||||
else {
|
||||
fail("Unexpected request");
|
||||
}
|
||||
}
|
||||
else {
|
||||
fail("Unexpected callback");
|
||||
}
|
||||
}
|
||||
};
|
||||
interceptor.setCallbackHandler(handler);
|
||||
interceptor.afterPropertiesSet();
|
||||
SOAPMessage message = loadSaajMessage("encrypted-soap.xml");
|
||||
SOAPMessage result = interceptor.validateMessage(message);
|
||||
assertNotNull("No result returned", result);
|
||||
assertXpathNotExists("Security Header not removed", "/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security", result);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.security.xwss;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
public abstract class XwssMessageInterceptorKeyStoreTestCase extends XwssMessageInterceptorTestCase {
|
||||
|
||||
protected X509Certificate certificate;
|
||||
|
||||
protected PrivateKey privateKey;
|
||||
|
||||
protected void onSetup() throws Exception {
|
||||
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = getClass().getResourceAsStream("test-keystore.jks");
|
||||
keyStore.load(is, "password".toCharArray());
|
||||
}
|
||||
finally {
|
||||
if (is != null) {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
certificate = (X509Certificate) keyStore.getCertificate("alias");
|
||||
privateKey = (PrivateKey) keyStore.getKey("alias", "password".toCharArray());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright 2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.security.xwss;
|
||||
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import javax.security.auth.callback.Callback;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
|
||||
import com.sun.xml.wss.impl.callback.CertificateValidationCallback;
|
||||
import com.sun.xml.wss.impl.callback.SignatureKeyCallback;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.ws.soap.security.xwss.callback.AbstractCallbackHandler;
|
||||
|
||||
public class XwssMessageInterceptorSignTest extends XwssMessageInterceptorKeyStoreTestCase {
|
||||
|
||||
public void testSignDefaultCertificate() throws Exception {
|
||||
interceptor.setPolicyConfiguration(new ClassPathResource("sign-config.xml", getClass()));
|
||||
CallbackHandler handler = new AbstractCallbackHandler() {
|
||||
|
||||
protected void handleInternal(Callback callback) {
|
||||
if (callback instanceof SignatureKeyCallback) {
|
||||
SignatureKeyCallback keyCallback = (SignatureKeyCallback) callback;
|
||||
if (keyCallback.getRequest() instanceof SignatureKeyCallback.DefaultPrivKeyCertRequest) {
|
||||
SignatureKeyCallback.DefaultPrivKeyCertRequest request =
|
||||
(SignatureKeyCallback.DefaultPrivKeyCertRequest) keyCallback.getRequest();
|
||||
request.setX509Certificate(certificate);
|
||||
request.setPrivateKey(privateKey);
|
||||
}
|
||||
else {
|
||||
fail("Unexpected request");
|
||||
}
|
||||
}
|
||||
else {
|
||||
fail("Unexpected callback");
|
||||
}
|
||||
}
|
||||
};
|
||||
interceptor.setCallbackHandler(handler);
|
||||
interceptor.afterPropertiesSet();
|
||||
SOAPMessage message = loadSaajMessage("empty-soap.xml");
|
||||
SOAPMessage result = interceptor.secureMessage(message);
|
||||
assertNotNull("No result returned", result);
|
||||
assertXpathExists("BinarySecurityToken does not exist",
|
||||
"SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/wsse:BinarySecurityToken", result);
|
||||
assertXpathExists("Signature does not exist", "/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/ds:Signature",
|
||||
result);
|
||||
}
|
||||
|
||||
public void testSignAlias() throws Exception {
|
||||
interceptor.setPolicyConfiguration(new ClassPathResource("sign-alias-config.xml", getClass()));
|
||||
CallbackHandler handler = new AbstractCallbackHandler() {
|
||||
|
||||
protected void handleInternal(Callback callback) {
|
||||
if (callback instanceof SignatureKeyCallback) {
|
||||
SignatureKeyCallback keyCallback = (SignatureKeyCallback) callback;
|
||||
if (keyCallback.getRequest() instanceof SignatureKeyCallback.AliasPrivKeyCertRequest) {
|
||||
SignatureKeyCallback.AliasPrivKeyCertRequest request =
|
||||
(SignatureKeyCallback.AliasPrivKeyCertRequest) keyCallback.getRequest();
|
||||
assertEquals("Invalid alias", "alias", request.getAlias());
|
||||
request.setX509Certificate(certificate);
|
||||
request.setPrivateKey(privateKey);
|
||||
}
|
||||
else {
|
||||
fail("Unexpected request");
|
||||
}
|
||||
}
|
||||
else {
|
||||
fail("Unexpected callback");
|
||||
}
|
||||
}
|
||||
};
|
||||
interceptor.setCallbackHandler(handler);
|
||||
interceptor.afterPropertiesSet();
|
||||
SOAPMessage message = loadSaajMessage("empty-soap.xml");
|
||||
SOAPMessage result = interceptor.secureMessage(message);
|
||||
assertNotNull("No result returned", result);
|
||||
assertXpathExists("BinarySecurityToken does not exist",
|
||||
"SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/wsse:BinarySecurityToken", result);
|
||||
assertXpathExists("Signature does not exist", "/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/ds:Signature",
|
||||
result);
|
||||
}
|
||||
|
||||
public void testValidateCertificate() throws Exception {
|
||||
interceptor.setPolicyConfiguration(new ClassPathResource("requireSignature-config.xml", getClass()));
|
||||
CallbackHandler handler = new AbstractCallbackHandler() {
|
||||
|
||||
protected void handleInternal(Callback callback) {
|
||||
if (callback instanceof CertificateValidationCallback) {
|
||||
CertificateValidationCallback validationCallback = (CertificateValidationCallback) callback;
|
||||
validationCallback.setValidator(new CertificateValidationCallback.CertificateValidator() {
|
||||
public boolean validate(X509Certificate passedCertificate) {
|
||||
assertEquals("Invalid certificate", certificate, passedCertificate);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
fail("Unexpected callback");
|
||||
}
|
||||
}
|
||||
};
|
||||
interceptor.setCallbackHandler(handler);
|
||||
interceptor.afterPropertiesSet();
|
||||
SOAPMessage message = loadSaajMessage("signed-soap.xml");
|
||||
SOAPMessage result = interceptor.validateMessage(message);
|
||||
assertNotNull("No result returned", result);
|
||||
assertXpathNotExists("Security Header not removed", "/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security", result);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.security.xwss;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.soap.MessageFactory;
|
||||
import javax.xml.soap.MimeHeaders;
|
||||
import javax.xml.soap.SOAPException;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import org.springframework.xml.xpath.XPathExpression;
|
||||
import org.springframework.xml.xpath.XPathExpressionFactory;
|
||||
|
||||
public abstract class XwssMessageInterceptorTestCase extends TestCase {
|
||||
|
||||
protected XwsSecurityInterceptor interceptor;
|
||||
|
||||
private MessageFactory messageFactory;
|
||||
|
||||
private Map namespaces;
|
||||
|
||||
protected final void setUp() throws Exception {
|
||||
interceptor = new XwsSecurityInterceptor();
|
||||
messageFactory = MessageFactory.newInstance();
|
||||
namespaces = new HashMap();
|
||||
namespaces.put("SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/");
|
||||
namespaces.put("wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
|
||||
namespaces.put("ds", "http://www.w3.org/2000/09/xmldsig#");
|
||||
namespaces.put("xenc", "http://www.w3.org/2001/04/xmlenc#");
|
||||
onSetup();
|
||||
}
|
||||
|
||||
protected void assertXpathEvaluatesTo(String message,
|
||||
String expectedValue,
|
||||
String xpathExpression,
|
||||
SOAPMessage soapMessage) {
|
||||
XPathExpression expression = XPathExpressionFactory.createXPathExpression(xpathExpression, namespaces);
|
||||
Document document = soapMessage.getSOAPPart();
|
||||
String actualValue = expression.evaluateAsString(document);
|
||||
assertEquals(message, expectedValue, actualValue);
|
||||
}
|
||||
|
||||
protected void assertXpathExists(String message, String xpathExpression, SOAPMessage soapMessage) {
|
||||
XPathExpression expression = XPathExpressionFactory.createXPathExpression(xpathExpression, namespaces);
|
||||
Document document = soapMessage.getSOAPPart();
|
||||
Node node = expression.evaluateAsNode(document);
|
||||
assertNotNull(message, node);
|
||||
}
|
||||
|
||||
protected void assertXpathNotExists(String message, String xpathExpression, SOAPMessage soapMessage) {
|
||||
XPathExpression expression = XPathExpressionFactory.createXPathExpression(xpathExpression, namespaces);
|
||||
Document document = soapMessage.getSOAPPart();
|
||||
Node node = expression.evaluateAsNode(document);
|
||||
assertNull(message, node);
|
||||
}
|
||||
|
||||
protected SOAPMessage loadSaajMessage(String fileName) throws SOAPException, IOException {
|
||||
MimeHeaders mimeHeaders = new MimeHeaders();
|
||||
mimeHeaders.addHeader("Content-Type", "text/xml");
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = getClass().getResourceAsStream(fileName);
|
||||
assertNotNull("Could not load SAAJ message with name [" + fileName + "]", is);
|
||||
return messageFactory.createMessage(mimeHeaders, is);
|
||||
}
|
||||
finally {
|
||||
if (is != null) {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void onSetup() throws Exception {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright 2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.security.xwss;
|
||||
|
||||
import javax.security.auth.callback.Callback;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
|
||||
import com.sun.xml.wss.impl.callback.PasswordCallback;
|
||||
import com.sun.xml.wss.impl.callback.PasswordValidationCallback;
|
||||
import com.sun.xml.wss.impl.callback.TimestampValidationCallback;
|
||||
import com.sun.xml.wss.impl.callback.UsernameCallback;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.ws.soap.security.xwss.callback.AbstractCallbackHandler;
|
||||
|
||||
public class XwssMessageInterceptorUsernameTokenTest extends XwssMessageInterceptorTestCase {
|
||||
|
||||
public void testAddUsernameTokenDigest() throws Exception {
|
||||
interceptor.setPolicyConfiguration(new ClassPathResource("usernameToken-digest-config.xml", getClass()));
|
||||
CallbackHandler handler = new AbstractCallbackHandler() {
|
||||
|
||||
protected void handleInternal(Callback callback) {
|
||||
if (callback instanceof UsernameCallback) {
|
||||
((UsernameCallback) callback).setUsername("Bert");
|
||||
}
|
||||
else if (callback instanceof PasswordCallback) {
|
||||
PasswordCallback passwordCallback = (PasswordCallback) callback;
|
||||
passwordCallback.setPassword("Ernie");
|
||||
}
|
||||
else {
|
||||
fail("Unexpected callback");
|
||||
}
|
||||
}
|
||||
};
|
||||
interceptor.setCallbackHandler(handler);
|
||||
interceptor.afterPropertiesSet();
|
||||
SOAPMessage message = loadSaajMessage("empty-soap.xml");
|
||||
SOAPMessage result = interceptor.secureMessage(message);
|
||||
assertNotNull("No result returned", result);
|
||||
assertXpathEvaluatesTo("Invalid Username",
|
||||
"Bert",
|
||||
"/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/wsse:UsernameToken/wsse:Username/text()",
|
||||
result);
|
||||
assertXpathExists("Password does not exist",
|
||||
"/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/wsse:UsernameToken/wsse:Password[@Type='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest']",
|
||||
result);
|
||||
}
|
||||
|
||||
public void testAddUsernameTokenPlainText() throws Exception {
|
||||
interceptor.setPolicyConfiguration(new ClassPathResource("usernameToken-plainText-config.xml", getClass()));
|
||||
CallbackHandler handler = new AbstractCallbackHandler() {
|
||||
|
||||
protected void handleInternal(Callback callback) {
|
||||
if (callback instanceof UsernameCallback) {
|
||||
((UsernameCallback) callback).setUsername("Bert");
|
||||
}
|
||||
else if (callback instanceof PasswordCallback) {
|
||||
PasswordCallback passwordCallback = (PasswordCallback) callback;
|
||||
passwordCallback.setPassword("Ernie");
|
||||
}
|
||||
else {
|
||||
fail("Unexpected callback");
|
||||
}
|
||||
}
|
||||
};
|
||||
interceptor.setCallbackHandler(handler);
|
||||
interceptor.afterPropertiesSet();
|
||||
SOAPMessage message = loadSaajMessage("empty-soap.xml");
|
||||
SOAPMessage result = interceptor.secureMessage(message);
|
||||
assertNotNull("No result returned", result);
|
||||
assertXpathEvaluatesTo("Invalid Username",
|
||||
"Bert",
|
||||
"/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/wsse:UsernameToken/wsse:Username/text()",
|
||||
result);
|
||||
assertXpathEvaluatesTo("Invalid Password",
|
||||
"Ernie",
|
||||
"/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/wsse:UsernameToken/wsse:Password[@Type='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText']/text()",
|
||||
result);
|
||||
}
|
||||
|
||||
public void testValidateUsernameTokenPlainText() throws Exception {
|
||||
interceptor
|
||||
.setPolicyConfiguration(new ClassPathResource("requireUsernameToken-plainText-config.xml", getClass()));
|
||||
CallbackHandler handler = new AbstractCallbackHandler() {
|
||||
|
||||
protected void handleInternal(Callback callback) {
|
||||
if (callback instanceof PasswordValidationCallback) {
|
||||
PasswordValidationCallback validationCallback = (PasswordValidationCallback) callback;
|
||||
validationCallback.setValidator(new PasswordValidationCallback.PasswordValidator() {
|
||||
public boolean validate(PasswordValidationCallback.Request request) {
|
||||
if (request instanceof PasswordValidationCallback.PlainTextPasswordRequest) {
|
||||
PasswordValidationCallback.PlainTextPasswordRequest passwordRequest =
|
||||
(PasswordValidationCallback.PlainTextPasswordRequest) request;
|
||||
assertEquals("Invalid username", "Bert", passwordRequest.getUsername());
|
||||
assertEquals("Invalid password", "Ernie", passwordRequest.getPassword());
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
fail("Unexpected request");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
fail("Unexpected callback");
|
||||
}
|
||||
}
|
||||
};
|
||||
interceptor.setCallbackHandler(handler);
|
||||
interceptor.afterPropertiesSet();
|
||||
SOAPMessage message = loadSaajMessage("usernameTokenPlainText-soap.xml");
|
||||
SOAPMessage result = interceptor.validateMessage(message);
|
||||
assertNotNull("No result returned", result);
|
||||
assertXpathNotExists("Security Header not removed", "/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security", result);
|
||||
}
|
||||
|
||||
public void testValidateUsernameTokenDigest() throws Exception {
|
||||
interceptor.setPolicyConfiguration(new ClassPathResource("requireUsernameToken-digest-config.xml", getClass()));
|
||||
CallbackHandler handler = new AbstractCallbackHandler() {
|
||||
|
||||
protected void handleInternal(Callback callback) {
|
||||
if (callback instanceof PasswordValidationCallback) {
|
||||
PasswordValidationCallback validationCallback = (PasswordValidationCallback) callback;
|
||||
if (validationCallback.getRequest() instanceof PasswordValidationCallback.DigestPasswordRequest) {
|
||||
PasswordValidationCallback.DigestPasswordRequest passwordRequest =
|
||||
(PasswordValidationCallback.DigestPasswordRequest) validationCallback.getRequest();
|
||||
assertEquals("Invalid username", "Bert", passwordRequest.getUsername());
|
||||
passwordRequest.setPassword("Ernie");
|
||||
validationCallback.setValidator(new PasswordValidationCallback.DigestPasswordValidator());
|
||||
}
|
||||
else {
|
||||
fail("Unexpected request");
|
||||
}
|
||||
}
|
||||
else if (callback instanceof TimestampValidationCallback) {
|
||||
TimestampValidationCallback validationCallback = (TimestampValidationCallback) callback;
|
||||
validationCallback.setValidator(new TimestampValidationCallback.TimestampValidator() {
|
||||
public void validate(TimestampValidationCallback.Request request) {
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
fail("Unexpected callback");
|
||||
}
|
||||
}
|
||||
};
|
||||
interceptor.setCallbackHandler(handler);
|
||||
interceptor.afterPropertiesSet();
|
||||
SOAPMessage message = loadSaajMessage("usernameTokenDigest-soap.xml");
|
||||
SOAPMessage result = interceptor.validateMessage(message);
|
||||
assertNotNull("No result returned", result);
|
||||
assertXpathNotExists("Security Header not removed", "/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security", result);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.security.xwss.callback;
|
||||
|
||||
import javax.security.auth.callback.Callback;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class CallbackHandlerChainTest extends TestCase {
|
||||
|
||||
private CallbackHandler supported = new CallbackHandler() {
|
||||
public void handle(Callback[] callbacks) {
|
||||
}
|
||||
};
|
||||
|
||||
private CallbackHandler unsupported = new CallbackHandler() {
|
||||
public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
|
||||
throw new UnsupportedCallbackException(callbacks[0]);
|
||||
}
|
||||
};
|
||||
|
||||
private Callback callback = new Callback() {
|
||||
};
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
}
|
||||
|
||||
public void testSupported() throws Exception {
|
||||
CallbackHandlerChain chain = new CallbackHandlerChain(new CallbackHandler[]{supported});
|
||||
chain.handle(new Callback[]{callback});
|
||||
}
|
||||
|
||||
public void testUnsupportedNormal() throws Exception {
|
||||
CallbackHandlerChain chain = new CallbackHandlerChain(new CallbackHandler[]{unsupported, supported});
|
||||
chain.handle(new Callback[]{callback});
|
||||
}
|
||||
|
||||
public void testUnsupported() throws Exception {
|
||||
CallbackHandlerChain chain = new CallbackHandlerChain(new CallbackHandler[]{unsupported});
|
||||
try {
|
||||
chain.handle(new Callback[]{callback});
|
||||
fail("Expected UnsupportedCallbackException");
|
||||
}
|
||||
catch (UnsupportedCallbackException ex) {
|
||||
// expected behavior
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.security.xwss.callback;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class KeyStoreCallbackHandlerTest extends TestCase {
|
||||
|
||||
private KeyStoreCallbackHandler handler;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
handler = new KeyStoreCallbackHandler();
|
||||
}
|
||||
|
||||
public void testLoadDefaultTrustStore() throws Exception {
|
||||
System.setProperty("javax.net.ssl.trustStore",
|
||||
"/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Home/");
|
||||
handler.loadDefaultTrustStore();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.security.xwss.callback;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import com.sun.xml.wss.impl.callback.PasswordValidationCallback;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class SimplePasswordValidationCallbackHandlerTest extends TestCase {
|
||||
|
||||
private SimplePasswordValidationCallbackHandler handler;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
handler = new SimplePasswordValidationCallbackHandler();
|
||||
Properties users = new Properties();
|
||||
users.setProperty("Bert", "Ernie");
|
||||
handler.setUsers(users);
|
||||
}
|
||||
|
||||
public void testPlainTextPasswordValid() throws Exception {
|
||||
PasswordValidationCallback.PlainTextPasswordRequest request =
|
||||
new PasswordValidationCallback.PlainTextPasswordRequest("Bert", "Ernie");
|
||||
PasswordValidationCallback callback = new PasswordValidationCallback(request);
|
||||
handler.handleInternal(callback);
|
||||
boolean authenticated = callback.getResult();
|
||||
assertTrue("Not authenticated", authenticated);
|
||||
}
|
||||
|
||||
public void testPlainTextPasswordInvalid() throws Exception {
|
||||
PasswordValidationCallback.PlainTextPasswordRequest request =
|
||||
new PasswordValidationCallback.PlainTextPasswordRequest("Bert", "Big bird");
|
||||
PasswordValidationCallback callback = new PasswordValidationCallback(request);
|
||||
handler.handleInternal(callback);
|
||||
boolean authenticated = callback.getResult();
|
||||
assertFalse("Authenticated", authenticated);
|
||||
}
|
||||
|
||||
public void testPlainTextPasswordNoSuchUser() throws Exception {
|
||||
PasswordValidationCallback.PlainTextPasswordRequest request =
|
||||
new PasswordValidationCallback.PlainTextPasswordRequest("Big bird", "Bert");
|
||||
PasswordValidationCallback callback = new PasswordValidationCallback(request);
|
||||
handler.handleInternal(callback);
|
||||
boolean authenticated = callback.getResult();
|
||||
assertFalse("Authenticated", authenticated);
|
||||
}
|
||||
|
||||
public void testDigestPasswordValid() throws Exception {
|
||||
String username = "Bert";
|
||||
String nonce = "9mdsYDCrjjYRur0rxzYt2oD7";
|
||||
String passwordDigest = "kwNstEaiFOrI7B31j7GuETYvdgk=";
|
||||
String creationTime = "2006-06-01T23:48:42Z";
|
||||
PasswordValidationCallback.DigestPasswordRequest request =
|
||||
new PasswordValidationCallback.DigestPasswordRequest(username, passwordDigest, nonce, creationTime);
|
||||
PasswordValidationCallback callback = new PasswordValidationCallback(request);
|
||||
handler.handleInternal(callback);
|
||||
boolean authenticated = callback.getResult();
|
||||
assertFalse("Authenticated", authenticated);
|
||||
|
||||
}
|
||||
|
||||
public void testDigestPasswordInvalid() throws Exception {
|
||||
String username = "Bert";
|
||||
String nonce = "9mdsYDCrjjYRur0rxzYt2oD7";
|
||||
String passwordDigest = "kwNstEaiFOrI7B31j7GuETYvdgk";
|
||||
String creationTime = "2006-06-01T23:48:42Z";
|
||||
PasswordValidationCallback.DigestPasswordRequest request =
|
||||
new PasswordValidationCallback.DigestPasswordRequest(username, passwordDigest, nonce, creationTime);
|
||||
PasswordValidationCallback callback = new PasswordValidationCallback(request);
|
||||
handler.handleInternal(callback);
|
||||
boolean authenticated = callback.getResult();
|
||||
assertFalse("Authenticated", authenticated);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.security.xwss.callback;
|
||||
|
||||
import com.sun.xml.wss.impl.callback.PasswordCallback;
|
||||
import com.sun.xml.wss.impl.callback.UsernameCallback;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class SimpleUsernamePasswordCallbackHandlerTest extends TestCase {
|
||||
|
||||
private SimpleUsernamePasswordCallbackHandler handler;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
handler = new SimpleUsernamePasswordCallbackHandler();
|
||||
handler.setUsername("Bert");
|
||||
handler.setPassword("Ernie");
|
||||
}
|
||||
|
||||
public void testUsernameCallback() throws Exception {
|
||||
UsernameCallback usernameCallback = new UsernameCallback();
|
||||
handler.handleInternal(usernameCallback);
|
||||
assertEquals("Invalid username", "Bert", usernameCallback.getUsername());
|
||||
}
|
||||
|
||||
public void testPasswordCallback() throws Exception {
|
||||
PasswordCallback passwordCallback = new PasswordCallback();
|
||||
handler.handleInternal(passwordCallback);
|
||||
assertEquals("Invalid username", "Ernie", passwordCallback.getPassword());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.security.xwss.callback.acegi;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.security.KeyStore;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import com.sun.xml.wss.impl.callback.CertificateValidationCallback;
|
||||
import junit.framework.TestCase;
|
||||
import org.acegisecurity.AuthenticationManager;
|
||||
import org.acegisecurity.BadCredentialsException;
|
||||
import org.acegisecurity.GrantedAuthority;
|
||||
import org.acegisecurity.providers.TestingAuthenticationToken;
|
||||
import org.acegisecurity.providers.x509.X509AuthenticationToken;
|
||||
import org.easymock.MockControl;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
public class AcegiCertificateValidationCallbackHandlerTest extends TestCase {
|
||||
|
||||
private AcegiCertificateValidationCallbackHandler callbackHandler;
|
||||
|
||||
private MockControl control;
|
||||
|
||||
private AuthenticationManager mock;
|
||||
|
||||
private X509Certificate certificate;
|
||||
|
||||
private CertificateValidationCallback callback;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
callbackHandler = new AcegiCertificateValidationCallbackHandler();
|
||||
control = MockControl.createControl(AuthenticationManager.class);
|
||||
mock = (AuthenticationManager) control.getMock();
|
||||
callbackHandler.setAuthenticationManager(mock);
|
||||
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = new ClassPathResource("/org/springframework/ws/soap/security/xwss/test-keystore.jks").getInputStream();
|
||||
keyStore.load(is, "password".toCharArray());
|
||||
}
|
||||
finally {
|
||||
if (is != null) {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
certificate = (X509Certificate) keyStore.getCertificate("alias");
|
||||
callback = new CertificateValidationCallback(certificate);
|
||||
}
|
||||
|
||||
public void testValidateCertificateValid() throws Exception {
|
||||
mock.authenticate(new X509AuthenticationToken(certificate));
|
||||
control.setMatcher(MockControl.ALWAYS_MATCHER);
|
||||
control.setReturnValue(new TestingAuthenticationToken(certificate, null, new GrantedAuthority[0]));
|
||||
control.replay();
|
||||
callbackHandler.handleInternal(callback);
|
||||
boolean authenticated = callback.getResult();
|
||||
assertTrue("Not authenticated", authenticated);
|
||||
control.verify();
|
||||
}
|
||||
|
||||
public void testValidateCertificateInvalid() throws Exception {
|
||||
mock.authenticate(new X509AuthenticationToken(certificate));
|
||||
control.setMatcher(MockControl.ALWAYS_MATCHER);
|
||||
control.setThrowable(new BadCredentialsException(""));
|
||||
control.replay();
|
||||
callbackHandler.handleInternal(callback);
|
||||
boolean authenticated = callback.getResult();
|
||||
assertFalse("Authenticated", authenticated);
|
||||
control.verify();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.security.xwss.callback.acegi;
|
||||
|
||||
import com.sun.xml.wss.impl.callback.PasswordValidationCallback;
|
||||
import junit.framework.TestCase;
|
||||
import org.acegisecurity.GrantedAuthority;
|
||||
import org.acegisecurity.userdetails.User;
|
||||
import org.acegisecurity.userdetails.UserDetailsService;
|
||||
import org.acegisecurity.userdetails.UsernameNotFoundException;
|
||||
import org.easymock.MockControl;
|
||||
|
||||
public class AcegiDigestPasswordValidationCallbackHandlerTest extends TestCase {
|
||||
|
||||
private AcegiDigestPasswordValidationCallbackHandler callbackHandler;
|
||||
|
||||
private MockControl control;
|
||||
|
||||
private UserDetailsService mock;
|
||||
|
||||
private String username;
|
||||
|
||||
private String password;
|
||||
|
||||
private PasswordValidationCallback callback;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
callbackHandler = new AcegiDigestPasswordValidationCallbackHandler();
|
||||
control = MockControl.createControl(UserDetailsService.class);
|
||||
mock = (UserDetailsService) control.getMock();
|
||||
callbackHandler.setUserDetailsService(mock);
|
||||
username = "Bert";
|
||||
password = "Ernie";
|
||||
String nonce = "9mdsYDCrjjYRur0rxzYt2oD7";
|
||||
String passwordDigest = "kwNstEaiFOrI7B31j7GuETYvdgk=";
|
||||
String creationTime = "2006-06-01T23:48:42Z";
|
||||
PasswordValidationCallback.DigestPasswordRequest request =
|
||||
new PasswordValidationCallback.DigestPasswordRequest(username, passwordDigest, nonce, creationTime);
|
||||
callback = new PasswordValidationCallback(request);
|
||||
}
|
||||
|
||||
public void testAuthenticateUserDigestUserNotFound() throws Exception {
|
||||
control.expectAndThrow(mock.loadUserByUsername(username), new UsernameNotFoundException(username));
|
||||
control.replay();
|
||||
callbackHandler.handleInternal(callback);
|
||||
boolean authenticated = callback.getResult();
|
||||
assertFalse("Authenticated", authenticated);
|
||||
control.verify();
|
||||
}
|
||||
|
||||
public void testAuthenticateUserDigestValid() throws Exception {
|
||||
User user = new User(username, password, true, true, true, true, new GrantedAuthority[0]);
|
||||
control.expectAndReturn(mock.loadUserByUsername(username), user);
|
||||
control.replay();
|
||||
callbackHandler.handleInternal(callback);
|
||||
boolean authenticated = callback.getResult();
|
||||
assertTrue("Not authenticated", authenticated);
|
||||
control.verify();
|
||||
}
|
||||
|
||||
public void testAuthenticateUserDigestValidInvalid() throws Exception {
|
||||
User user = new User(username, "Big bird", true, true, true, true, new GrantedAuthority[0]);
|
||||
control.expectAndReturn(mock.loadUserByUsername(username), user);
|
||||
control.replay();
|
||||
callbackHandler.handleInternal(callback);
|
||||
boolean authenticated = callback.getResult();
|
||||
assertFalse("Authenticated", authenticated);
|
||||
control.verify();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.security.xwss.callback.acegi;
|
||||
|
||||
import com.sun.xml.wss.impl.callback.PasswordValidationCallback;
|
||||
import junit.framework.TestCase;
|
||||
import org.acegisecurity.Authentication;
|
||||
import org.acegisecurity.AuthenticationManager;
|
||||
import org.acegisecurity.BadCredentialsException;
|
||||
import org.acegisecurity.GrantedAuthority;
|
||||
import org.acegisecurity.providers.TestingAuthenticationToken;
|
||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
import org.easymock.MockControl;
|
||||
|
||||
public class AcegiPlainTextPasswordValidationCallbackHandlerTest extends TestCase {
|
||||
|
||||
private AcegiPlainTextPasswordValidationCallbackHandler callbackHandler;
|
||||
|
||||
private MockControl control;
|
||||
|
||||
private AuthenticationManager mock;
|
||||
|
||||
private PasswordValidationCallback callback;
|
||||
|
||||
private String username;
|
||||
|
||||
private String password;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
callbackHandler = new AcegiPlainTextPasswordValidationCallbackHandler();
|
||||
control = MockControl.createControl(AuthenticationManager.class);
|
||||
mock = (AuthenticationManager) control.getMock();
|
||||
callbackHandler.setAuthenticationManager(mock);
|
||||
username = "Bert";
|
||||
password = "Ernie";
|
||||
PasswordValidationCallback.PlainTextPasswordRequest request =
|
||||
new PasswordValidationCallback.PlainTextPasswordRequest(username, password);
|
||||
callback = new PasswordValidationCallback(request);
|
||||
}
|
||||
|
||||
public void testAuthenticateUserPlainTextValid() throws Exception {
|
||||
Authentication authResult = new TestingAuthenticationToken(username, password, new GrantedAuthority[0]);
|
||||
control.expectAndReturn(mock.authenticate(new UsernamePasswordAuthenticationToken(username, password)),
|
||||
authResult);
|
||||
control.replay();
|
||||
callbackHandler.handleInternal(callback);
|
||||
boolean authenticated = callback.getResult();
|
||||
assertTrue("Not authenticated", authenticated);
|
||||
control.verify();
|
||||
}
|
||||
|
||||
public void testAuthenticateUserPlainTextInvalid() throws Exception {
|
||||
control.expectAndThrow(mock.authenticate(new UsernamePasswordAuthenticationToken(username, password)),
|
||||
new BadCredentialsException(""));
|
||||
control.replay();
|
||||
callbackHandler.handleInternal(callback);
|
||||
boolean authenticated = callback.getResult();
|
||||
assertFalse("Authenticated", authenticated);
|
||||
control.verify();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.security.xwss.callback.jaas;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.security.auth.login.LoginException;
|
||||
import javax.security.auth.spi.LoginModule;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
public class CertificateLoginModule implements LoginModule {
|
||||
|
||||
private Subject subject;
|
||||
|
||||
private boolean loginSuccessful = false;
|
||||
|
||||
public boolean abort() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean commit() {
|
||||
if (!loginSuccessful) {
|
||||
subject.getPrincipals().clear();
|
||||
subject.getPrivateCredentials().clear();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void initialize(Subject subject,
|
||||
CallbackHandler callbackHandler,
|
||||
java.util.Map sharedState,
|
||||
java.util.Map options) {
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
public boolean login() throws LoginException {
|
||||
if (subject == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String name = getName(subject);
|
||||
|
||||
loginSuccessful = "CN=Arjen Poutsma,OU=Spring-WS,O=Interface21,L=Amsterdam,ST=Unknown,C=NL".equals(name);
|
||||
return loginSuccessful;
|
||||
}
|
||||
|
||||
public boolean logout() {
|
||||
subject.getPrincipals().clear();
|
||||
subject.getPrivateCredentials().clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
private String getName(Subject subject) {
|
||||
for (Iterator iterator = subject.getPrincipals().iterator(); iterator.hasNext();) {
|
||||
Principal principal = (Principal) iterator.next();
|
||||
if (principal instanceof X500Principal) {
|
||||
return ((X500Principal) principal).getName();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.security.xwss.callback.jaas;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.security.KeyStore;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import com.sun.xml.wss.impl.callback.CertificateValidationCallback;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
public class JaasCertificateValidationCallbackHandlerTest extends TestCase {
|
||||
|
||||
private JaasCertificateValidationCallbackHandler callbackHandler;
|
||||
|
||||
private CertificateValidationCallback callback;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
System.setProperty("java.security.auth.login.config", getClass().getResource("jaas.config").toString());
|
||||
callbackHandler = new JaasCertificateValidationCallbackHandler();
|
||||
callbackHandler.setLoginContextName("Certificate");
|
||||
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = new ClassPathResource("/org/springframework/ws/soap/security/xwss/test-keystore.jks").getInputStream();
|
||||
keyStore.load(is, "password".toCharArray());
|
||||
}
|
||||
finally {
|
||||
if (is != null) {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
X509Certificate certificate = (X509Certificate) keyStore.getCertificate("alias");
|
||||
callback = new CertificateValidationCallback(certificate);
|
||||
}
|
||||
|
||||
public void testValidateCertificateValid() throws Exception {
|
||||
callbackHandler.handleInternal(callback);
|
||||
boolean authenticated = callback.getResult();
|
||||
assertTrue("Not authenticated", authenticated);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.security.xwss.callback.jaas;
|
||||
|
||||
import com.sun.xml.wss.impl.callback.PasswordValidationCallback;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class JaasPlainTextPasswordValidationCallbackHandlerTest extends TestCase {
|
||||
|
||||
private JaasPlainTextPasswordValidationCallbackHandler callbackHandler;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
System.setProperty("java.security.auth.login.config", getClass().getResource("jaas.config").toString());
|
||||
callbackHandler = new JaasPlainTextPasswordValidationCallbackHandler();
|
||||
callbackHandler.setLoginContextName("PlainText");
|
||||
}
|
||||
|
||||
public void testAuthenticateUserPlainTextValid() throws Exception {
|
||||
PasswordValidationCallback.PlainTextPasswordRequest request =
|
||||
new PasswordValidationCallback.PlainTextPasswordRequest("Bert", "Ernie");
|
||||
PasswordValidationCallback callback = new PasswordValidationCallback(request);
|
||||
callbackHandler.handleInternal(callback);
|
||||
boolean authenticated = callback.getResult();
|
||||
assertTrue("Not authenticated", authenticated);
|
||||
}
|
||||
|
||||
public void testAuthenticateUserPlainTextInvalid() throws Exception {
|
||||
PasswordValidationCallback.PlainTextPasswordRequest request =
|
||||
new PasswordValidationCallback.PlainTextPasswordRequest("Bert", "Big bird");
|
||||
PasswordValidationCallback callback = new PasswordValidationCallback(request);
|
||||
callbackHandler.handleInternal(callback);
|
||||
boolean authenticated = callback.getResult();
|
||||
assertFalse("Authenticated", authenticated);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright 2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.security.xwss.callback.jaas;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.callback.Callback;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.security.auth.callback.NameCallback;
|
||||
import javax.security.auth.callback.PasswordCallback;
|
||||
import javax.security.auth.login.LoginException;
|
||||
import javax.security.auth.spi.LoginModule;
|
||||
|
||||
public class PlainTextLoginModule implements LoginModule {
|
||||
|
||||
private Subject subject;
|
||||
|
||||
private CallbackHandler callbackHandler;
|
||||
|
||||
private boolean success;
|
||||
|
||||
private List principals = new ArrayList();
|
||||
|
||||
public boolean abort() {
|
||||
success = false;
|
||||
logout();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean commit() throws LoginException {
|
||||
if (success) {
|
||||
if (subject.isReadOnly()) {
|
||||
throw new LoginException("Subject is read-only");
|
||||
}
|
||||
try {
|
||||
subject.getPrincipals().addAll(principals);
|
||||
principals.clear();
|
||||
return true;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new LoginException(e.getMessage());
|
||||
}
|
||||
}
|
||||
else {
|
||||
principals.clear();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void initialize(Subject subject,
|
||||
CallbackHandler callbackHandler,
|
||||
java.util.Map sharedState,
|
||||
java.util.Map options) {
|
||||
this.subject = subject;
|
||||
this.callbackHandler = callbackHandler;
|
||||
}
|
||||
|
||||
public boolean login() throws LoginException {
|
||||
if (callbackHandler == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
NameCallback nameCallback = new NameCallback("Username: ");
|
||||
PasswordCallback passwordCallback = new PasswordCallback("Password: ", false);
|
||||
Callback[] callbacks = new Callback[]{nameCallback, passwordCallback};
|
||||
|
||||
callbackHandler.handle(callbacks);
|
||||
|
||||
String username = nameCallback.getName();
|
||||
String password = new String(passwordCallback.getPassword());
|
||||
|
||||
((PasswordCallback) callbacks[1]).clearPassword();
|
||||
|
||||
success = validate(username, password);
|
||||
|
||||
callbacks[0] = null;
|
||||
callbacks[1] = null;
|
||||
|
||||
if (!success) {
|
||||
throw new LoginException("Authentication failed: Password does not match");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (LoginException ex) {
|
||||
throw ex;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
success = false;
|
||||
throw new LoginException(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean validate(String username, String password) {
|
||||
if ("Bert".equals(username) && "Ernie".equals(password)) {
|
||||
this.principals.add(new SimplePrincipal(username));
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean logout() {
|
||||
principals.clear();
|
||||
|
||||
Iterator iterator = subject.getPrincipals(SimplePrincipal.class).iterator();
|
||||
while (iterator.hasNext()) {
|
||||
SimplePrincipal principal = (SimplePrincipal) iterator.next();
|
||||
subject.getPrincipals().remove(principal);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.security.xwss.callback.jaas;
|
||||
|
||||
import java.security.Principal;
|
||||
|
||||
public final class SimplePrincipal implements Principal {
|
||||
|
||||
private String name;
|
||||
|
||||
public SimplePrincipal() {
|
||||
name = "";
|
||||
}
|
||||
|
||||
public SimplePrincipal(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return name.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof SimplePrincipal)) {
|
||||
return false;
|
||||
}
|
||||
return name.equals(((SimplePrincipal) o).name);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user