SWS-955 - Add method for configuring SAML callback.
This commit is contained in:
committed by
Greg Turnquist
parent
05092c3333
commit
e34fb937d1
@@ -143,6 +143,8 @@ public class Wss4jSecurityInterceptor extends AbstractWsSecurityInterceptor impl
|
||||
|
||||
private boolean securementUseDerivedKey;
|
||||
|
||||
private CallbackHandler samlCallbackHandler;
|
||||
|
||||
// Allow RSA 15 to maintain default behavior
|
||||
private boolean allowRSA15KeyTransportAlgorithm = true;
|
||||
|
||||
@@ -373,6 +375,15 @@ public class Wss4jSecurityInterceptor extends AbstractWsSecurityInterceptor impl
|
||||
public void setSecurementUseDerivedKey(boolean securementUseDerivedKey) {
|
||||
this.securementUseDerivedKey = securementUseDerivedKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the SAML Callback used for generating SAML tokens.
|
||||
*
|
||||
* @param samlCallback
|
||||
*/
|
||||
public void setSecurementSamlCallbackHandler(CallbackHandler samlCallbackHandler) {
|
||||
this.samlCallbackHandler = samlCallbackHandler;
|
||||
}
|
||||
|
||||
/** Sets the server-side time to live */
|
||||
public void setValidationTimeToLive(int validationTimeToLive) {
|
||||
@@ -595,7 +606,11 @@ public class Wss4jSecurityInterceptor extends AbstractWsSecurityInterceptor impl
|
||||
requestData.setWssConfig(wssConfig);
|
||||
|
||||
messageContext.setProperty(WSHandlerConstants.TTL_TIMESTAMP, Integer.toString(securementTimeToLive));
|
||||
|
||||
|
||||
if (this.samlCallbackHandler != null) {
|
||||
messageContext.setProperty(WSHandlerConstants.SAML_CALLBACK_REF, this.samlCallbackHandler);
|
||||
}
|
||||
|
||||
// allow for qualified password types for .Net interoperability
|
||||
requestData.setAllowNamespaceQualifiedPasswordTypes(true);
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package org.springframework.ws.soap.security.wss4j2;
|
||||
|
||||
public class AxiomWss4jMessageInterceptorSamlTest extends Wss4jMessageInterceptorSamlTestCase {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package org.springframework.ws.soap.security.wss4j2;
|
||||
|
||||
public class SaajWss4jMessageInterceptorSamlTest extends Wss4jMessageInterceptorSamlTestCase {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package org.springframework.ws.soap.security.wss4j2;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import javax.security.auth.callback.Callback;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||
|
||||
import org.apache.wss4j.common.crypto.Crypto;
|
||||
import org.apache.wss4j.common.crypto.CryptoType;
|
||||
import org.apache.wss4j.common.crypto.Merlin;
|
||||
import org.apache.wss4j.common.saml.SAMLCallback;
|
||||
import org.apache.wss4j.common.saml.bean.KeyInfoBean;
|
||||
import org.apache.wss4j.common.saml.bean.SubjectBean;
|
||||
import org.apache.wss4j.common.saml.bean.Version;
|
||||
import org.apache.wss4j.common.saml.builder.SAML2Constants;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.soap.SoapMessage;
|
||||
import org.springframework.ws.soap.security.wss4j2.support.CryptoFactoryBean;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
public abstract class Wss4jMessageInterceptorSamlTestCase extends Wss4jTestCase {
|
||||
|
||||
protected Wss4jSecurityInterceptor interceptor;
|
||||
|
||||
@Override
|
||||
protected void onSetup() throws Exception {
|
||||
interceptor = new Wss4jSecurityInterceptor();
|
||||
interceptor.setSecurementActions("SAMLTokenSigned");
|
||||
interceptor.setValidationActions("SAMLTokenSigned Signature");
|
||||
CryptoFactoryBean cryptoFactoryBean = new CryptoFactoryBean();
|
||||
cryptoFactoryBean.setCryptoProvider(Merlin.class);
|
||||
cryptoFactoryBean.setKeyStoreType("jceks");
|
||||
cryptoFactoryBean.setKeyStorePassword("123456");
|
||||
cryptoFactoryBean.setKeyStoreLocation(new ClassPathResource("private.jks"));
|
||||
cryptoFactoryBean.afterPropertiesSet();
|
||||
Crypto crypto = cryptoFactoryBean.getObject();
|
||||
|
||||
CryptoType type = new CryptoType(CryptoType.TYPE.ALIAS);
|
||||
type.setAlias("rsaKey");
|
||||
X509Certificate userCertificate = crypto.getX509Certificates(type)[0];
|
||||
|
||||
interceptor.setSecurementSignatureCrypto(crypto);
|
||||
interceptor.setValidationSignatureCrypto(crypto);
|
||||
interceptor.setSecurementSamlCallbackHandler(getSamlCalbackHandler(crypto, userCertificate));
|
||||
interceptor.afterPropertiesSet();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddSAML() throws Exception
|
||||
{
|
||||
interceptor.setSecurementPassword("123456");
|
||||
interceptor.setSecurementUsername("rsaKey");
|
||||
SoapMessage message = loadSoap11Message("empty-soap.xml");
|
||||
MessageContext messageContext = getSoap11MessageContext(message);
|
||||
|
||||
interceptor.secureMessage(message, messageContext);
|
||||
Document document = getDocument(message);
|
||||
|
||||
assertXpathExists("Absent SAML Assertion element",
|
||||
"/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/saml:Assertion", document);
|
||||
|
||||
// lets verify the signature that we've just generated
|
||||
interceptor.validateMessage(message, messageContext);
|
||||
}
|
||||
|
||||
protected CallbackHandler getSamlCalbackHandler(Crypto crypto, X509Certificate userCert)
|
||||
{
|
||||
return new SamlCallbackHandler(crypto, userCert);
|
||||
}
|
||||
|
||||
private class SamlCallbackHandler implements CallbackHandler {
|
||||
|
||||
private Crypto crypto;
|
||||
|
||||
private X509Certificate userCertificate;
|
||||
|
||||
public SamlCallbackHandler(Crypto crypto, X509Certificate userCertificate)
|
||||
{
|
||||
this.crypto = crypto;
|
||||
this.userCertificate = userCertificate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
|
||||
|
||||
for (int i = 0; i < callbacks.length; i++) {
|
||||
if (callbacks[i] instanceof SAMLCallback) {
|
||||
SAMLCallback callback = (SAMLCallback) callbacks[i];
|
||||
callback.setSamlVersion(Version.SAML_20);
|
||||
callback.setIssuerCrypto(crypto);
|
||||
callback.setIssuerKeyName("rsaKey");
|
||||
callback.setIssuerKeyPassword("123456");
|
||||
callback.setIssuer("test-issuer");
|
||||
SubjectBean subject = new SubjectBean("test-subject", "", SAML2Constants.CONF_BEARER);
|
||||
KeyInfoBean keyInfo = new KeyInfoBean();
|
||||
keyInfo.setCertificate(userCertificate);
|
||||
subject.setKeyInfo(keyInfo);
|
||||
callback.setSubject(subject);
|
||||
callback.setSignAssertion(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -79,6 +79,7 @@ public abstract class Wss4jTestCase {
|
||||
namespaces.put("echo", "http://www.springframework.org/spring-ws/samples/echo");
|
||||
namespaces.put("wsu",
|
||||
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
|
||||
namespaces.put("saml", "urn:oasis:names:tc:SAML:2.0:assertion");
|
||||
namespaces.put("test", "http://test");
|
||||
xpathTemplate.setNamespaces(namespaces);
|
||||
onSetup();
|
||||
|
||||
Reference in New Issue
Block a user