You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2013/04/29 16:16:01 UTC
svn commit: r1477091 - in
/cxf/branches/wss4j2.0-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j:
AbstractWSS4JStaxInterceptor.java WSS4JStaxInInterceptor.java
WSS4JStaxOutInterceptor.java
Author: coheigea
Date: Mon Apr 29 14:16:01 2013
New Revision: 1477091
URL: http://svn.apache.org/r1477091
Log:
More configuration work for WSS4J 2.0
Modified:
cxf/branches/wss4j2.0-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JStaxInterceptor.java
cxf/branches/wss4j2.0-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxInInterceptor.java
cxf/branches/wss4j2.0-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxOutInterceptor.java
Modified: cxf/branches/wss4j2.0-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JStaxInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/branches/wss4j2.0-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JStaxInterceptor.java?rev=1477091&r1=1477090&r2=1477091&view=diff
==============================================================================
--- cxf/branches/wss4j2.0-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JStaxInterceptor.java (original)
+++ cxf/branches/wss4j2.0-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JStaxInterceptor.java Mon Apr 29 14:16:01 2013
@@ -18,22 +18,37 @@
*/
package org.apache.cxf.ws.security.wss4j;
+import java.io.InputStream;
import java.net.URI;
+import java.net.URL;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
+import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
import javax.xml.namespace.QName;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.SoapInterceptor;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.classloader.ClassLoaderUtils.ClassLoaderHolder;
+import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.phase.PhaseInterceptor;
+import org.apache.cxf.resource.ResourceManager;
+import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.wss4j.common.ConfigurationConstants;
+import org.apache.wss4j.common.crypto.Crypto;
+import org.apache.wss4j.common.crypto.CryptoFactory;
+import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.util.Loader;
import org.apache.wss4j.stax.ext.WSSConstants;
+import org.apache.wss4j.stax.ext.WSSSecurityProperties;
public abstract class AbstractWSS4JStaxInterceptor implements SoapInterceptor,
PhaseInterceptor<SoapMessage> {
@@ -44,8 +59,12 @@ public abstract class AbstractWSS4JStaxI
HEADERS.add(new QName(WSSConstants.NS_WSSE11, "Security"));
HEADERS.add(new QName(WSSConstants.NS_XMLENC, "EncryptedData"));
}
+
+ private static final Logger LOG = LogUtils.getL7dLogger(AbstractWSS4JStaxInterceptor.class);
private Map<String, Object> properties = new ConcurrentHashMap<String, Object>();
+ private Map<String, Crypto> cryptos = new ConcurrentHashMap<String, Crypto>();
+ private WSSSecurityProperties securityProperties;
private Set<String> before = new HashSet<String>();
private Set<String> after = new HashSet<String>();
private String phase;
@@ -55,6 +74,81 @@ public abstract class AbstractWSS4JStaxI
super();
id = getClass().getName();
}
+
+ public AbstractWSS4JStaxInterceptor(Map<String, Object> properties) {
+ this();
+ this.properties.putAll(properties);
+ }
+
+ protected void translateProperties(SoapMessage msg) {
+ String bspCompliant = (String)msg.getContextualProperty(SecurityConstants.IS_BSP_COMPLIANT);
+ if (bspCompliant != null) {
+ if (securityProperties != null) {
+ securityProperties.setDisableBSPEnforcement(Boolean.valueOf(bspCompliant));
+ } else {
+ properties.put(ConfigurationConstants.IS_BSP_COMPLIANT, bspCompliant);
+ }
+ }
+ String futureTTL =
+ (String)msg.getContextualProperty(SecurityConstants.TIMESTAMP_FUTURE_TTL);
+ if (futureTTL != null) {
+ if (securityProperties != null) {
+ securityProperties.setTimeStampFutureTTL(Integer.parseInt(futureTTL));
+ } else {
+ properties.put(ConfigurationConstants.TTL_FUTURE_TIMESTAMP, futureTTL);
+ }
+ }
+ String ttl =
+ (String)msg.getContextualProperty(SecurityConstants.TIMESTAMP_TTL);
+ if (ttl != null) {
+ if (securityProperties != null) {
+ securityProperties.setTimestampTTL(Integer.parseInt(ttl));
+ } else {
+ properties.put(ConfigurationConstants.TTL_TIMESTAMP, ttl);
+ }
+ }
+
+ String utFutureTTL =
+ (String)msg.getContextualProperty(SecurityConstants.USERNAMETOKEN_FUTURE_TTL);
+ if (utFutureTTL != null) {
+ if (securityProperties != null) {
+ securityProperties.setUtFutureTTL(Integer.parseInt(utFutureTTL));
+ } else {
+ properties.put(ConfigurationConstants.TTL_FUTURE_USERNAMETOKEN, utFutureTTL);
+ }
+ }
+ String utTTL =
+ (String)msg.getContextualProperty(SecurityConstants.USERNAMETOKEN_TTL);
+ if (utTTL != null) {
+ if (securityProperties != null) {
+ securityProperties.setUtTTL(Integer.parseInt(utTTL));
+ } else {
+ properties.put(ConfigurationConstants.TTL_USERNAMETOKEN, utTTL);
+ }
+ }
+
+ String certConstraints =
+ (String)msg.getContextualProperty(SecurityConstants.SUBJECT_CERT_CONSTRAINTS);
+ if (certConstraints != null) {
+ if (securityProperties != null) {
+ // TODO
+ } else {
+ properties.put(ConfigurationConstants.SIG_SUBJECT_CERT_CONSTRAINTS, certConstraints);
+ }
+ }
+
+ // Now set SAML SenderVouches + Holder Of Key requirements
+ String validateSAMLSubjectConf =
+ (String)msg.getContextualProperty(SecurityConstants.VALIDATE_SAML_SUBJECT_CONFIRMATION);
+ if (validateSAMLSubjectConf != null) {
+ if (securityProperties != null) {
+ securityProperties.setValidateSamlSubjectConfirmation(Boolean.valueOf(validateSAMLSubjectConf));
+ } else {
+ properties.put(ConfigurationConstants.VALIDATE_SAML_SUBJECT_CONFIRMATION,
+ validateSAMLSubjectConf);
+ }
+ }
+ }
public Set<URI> getRoles() {
return null;
@@ -121,10 +215,6 @@ public abstract class AbstractWSS4JStaxI
return properties;
}
- public void setProperties(Map<String, Object> properties) {
- this.properties = properties;
- }
-
public Set<String> getAfter() {
return after;
}
@@ -143,6 +233,113 @@ public abstract class AbstractWSS4JStaxI
protected boolean isRequestor(SoapMessage message) {
return MessageUtils.isRequestor(message);
+ }
+
+ public WSSSecurityProperties getSecurityProperties() {
+ return securityProperties;
+ }
+
+ public void setSecurityProperties(WSSSecurityProperties securityProperties) {
+ this.securityProperties = securityProperties;
}
+ /**
+ * Load a Crypto instance. Firstly, it tries to use the cryptoPropertyRefId tag to retrieve
+ * a Crypto object via a custom reference Id. Failing this, it tries to load the crypto
+ * instance via the cryptoPropertyFile tag.
+ */
+ protected Crypto loadCrypto(
+ SoapMessage soapMessage,
+ String cryptoPropertyFile,
+ String cryptoPropertyRefId
+ ) throws WSSecurityException {
+ Crypto crypto = null;
+
+ //
+ // Try the Property Ref Id first
+ //
+ String refId = (String)getProperty(soapMessage, cryptoPropertyRefId);
+ if (refId != null) {
+ crypto = cryptos.get(refId);
+ if (crypto == null) {
+ Object obj = getProperty(soapMessage, refId);
+ if (obj instanceof Properties) {
+ crypto = CryptoFactory.getInstance((Properties)obj);
+ cryptos.put(refId, crypto);
+ } else if (obj instanceof Crypto) {
+ crypto = (Crypto)obj;
+ cryptos.put(refId, crypto);
+ }
+ }
+ if (crypto == null) {
+ LOG.info("The Crypto reference " + refId + " specified by "
+ + cryptoPropertyRefId + " could not be loaded"
+ );
+ }
+ }
+
+ //
+ // Now try loading the properties file
+ //
+ if (crypto == null) {
+ String propFile = (String)getProperty(soapMessage, cryptoPropertyFile);
+ if (propFile != null) {
+ crypto = cryptos.get(propFile);
+ if (crypto == null) {
+ crypto = loadCryptoFromPropertiesFile(soapMessage, propFile);
+ cryptos.put(propFile, crypto);
+ }
+ if (crypto == null) {
+ LOG.info(
+ "The Crypto properties file " + propFile + " specified by "
+ + cryptoPropertyFile + " could not be loaded or found"
+ );
+ }
+ }
+ }
+
+ return crypto;
+ }
+
+ protected Crypto loadCryptoFromPropertiesFile(
+ SoapMessage soapMessage, String propFilename
+ ) throws WSSecurityException {
+ ClassLoaderHolder orig = null;
+ try {
+ try {
+ URL url = ClassLoaderUtils.getResource(propFilename, this.getClass());
+ if (url == null) {
+ ResourceManager manager = soapMessage.getExchange()
+ .getBus().getExtension(ResourceManager.class);
+ ClassLoader loader = manager.resolveResource("", ClassLoader.class);
+ if (loader != null) {
+ orig = ClassLoaderUtils.setThreadContextClassloader(loader);
+ }
+ url = manager.resolveResource(propFilename, URL.class);
+ }
+ if (url != null) {
+ Properties props = new Properties();
+ InputStream in = url.openStream();
+ props.load(in);
+ in.close();
+ return CryptoFactory.getInstance(props, getClassLoader());
+ }
+ } catch (Exception e) {
+ //ignore
+ }
+ return CryptoFactory.getInstance(propFilename, getClassLoader());
+ } finally {
+ if (orig != null) {
+ orig.reset();
+ }
+ }
+ }
+
+ private ClassLoader getClassLoader() {
+ try {
+ return Loader.getTCL();
+ } catch (Exception ex) {
+ return null;
+ }
+ }
}
Modified: cxf/branches/wss4j2.0-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/branches/wss4j2.0-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxInInterceptor.java?rev=1477091&r1=1477090&r2=1477091&view=diff
==============================================================================
--- cxf/branches/wss4j2.0-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxInInterceptor.java (original)
+++ cxf/branches/wss4j2.0-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxInInterceptor.java Mon Apr 29 14:16:01 2013
@@ -20,20 +20,28 @@ package org.apache.cxf.ws.security.wss4j
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.logging.Logger;
+import javax.security.auth.callback.CallbackHandler;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.apache.cxf.binding.soap.SoapFault;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.SoapVersion;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
import org.apache.cxf.common.i18n.Message;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.interceptor.StaxInInterceptor;
import org.apache.cxf.interceptor.URIMappingInterceptor;
+import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.phase.Phase;
+import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.wss4j.common.ConfigurationConstants;
+import org.apache.wss4j.common.cache.ReplayCache;
+import org.apache.wss4j.common.crypto.Crypto;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.stax.WSSec;
import org.apache.wss4j.stax.ext.InboundWSSec;
@@ -46,15 +54,19 @@ public class WSS4JStaxInInterceptor exte
private static final Logger LOG = LogUtils.getL7dLogger(WSS4JStaxInInterceptor.class);
- private final InboundWSSec inboundWSSec;
private List<XMLSecurityConstants.Action> inActions;
public WSS4JStaxInInterceptor(WSSSecurityProperties securityProperties) throws WSSecurityException {
super();
setPhase(Phase.POST_STREAM);
getAfter().add(StaxInInterceptor.class.getName());
-
- inboundWSSec = WSSec.getInboundWSSec(securityProperties);
+ setSecurityProperties(securityProperties);
+ }
+
+ public WSS4JStaxInInterceptor(Map<String, Object> props) throws WSSecurityException {
+ super(props);
+ setPhase(Phase.POST_STREAM);
+ getAfter().add(StaxInInterceptor.class.getName());
}
public final boolean isGET(SoapMessage message) {
@@ -97,6 +109,18 @@ public class WSS4JStaxInInterceptor exte
@SuppressWarnings("unchecked")
final List<SecurityEvent> requestSecurityEvents =
(List<SecurityEvent>) soapMessage.getExchange().get(SecurityEvent.class.getName() + ".out");
+
+ translateProperties(soapMessage);
+ configureProperties(soapMessage);
+ configureCallbackHandler(soapMessage);
+
+ InboundWSSec inboundWSSec = null;
+ if (getSecurityProperties() != null) {
+ inboundWSSec = WSSec.getInboundWSSec(getSecurityProperties());
+ } else {
+ inboundWSSec = WSSec.getInboundWSSec(getProperties());
+ }
+
newXmlStreamReader =
inboundWSSec.processInMessage(originalXmlStreamReader, requestSecurityEvents, securityEventListener);
soapMessage.setContent(XMLStreamReader.class, newXmlStreamReader);
@@ -113,6 +137,86 @@ public class WSS4JStaxInInterceptor exte
throw new SoapFault(new Message("STAX_EX", LOG), e, soapMessage.getVersion().getSender());
}
}
+
+ private void configureProperties(SoapMessage msg) throws WSSecurityException {
+ WSSSecurityProperties securityProperties = getSecurityProperties();
+ Map<String, Object> config = getProperties();
+
+ // Configure replay caching
+ ReplayCache nonceCache =
+ WSS4JUtils.getReplayCache(
+ msg, SecurityConstants.ENABLE_NONCE_CACHE, SecurityConstants.NONCE_CACHE_INSTANCE
+ );
+ if (securityProperties != null) {
+ securityProperties.setNonceReplayCache(nonceCache);
+ } else {
+ config.put(ConfigurationConstants.NONCE_CACHE_INSTANCE, nonceCache);
+ }
+
+ ReplayCache timestampCache =
+ WSS4JUtils.getReplayCache(
+ msg, SecurityConstants.ENABLE_TIMESTAMP_CACHE, SecurityConstants.TIMESTAMP_CACHE_INSTANCE
+ );
+ if (securityProperties != null) {
+ securityProperties.setTimestampReplayCache(timestampCache);
+ } else {
+ config.put(ConfigurationConstants.TIMESTAMP_CACHE_INSTANCE, timestampCache);
+ }
+
+ boolean enableRevocation =
+ MessageUtils.isTrue(msg.getContextualProperty(SecurityConstants.ENABLE_REVOCATION));
+ if (securityProperties != null) {
+ securityProperties.setEnableRevocation(enableRevocation);
+ } else {
+ config.put(ConfigurationConstants.ENABLE_REVOCATION, Boolean.toString(enableRevocation));
+ }
+
+ // Crypto loading only applies for Map
+ if (config != null) {
+ Crypto sigVerCrypto =
+ loadCrypto(
+ msg,
+ ConfigurationConstants.SIG_VER_PROP_FILE,
+ ConfigurationConstants.SIG_VER_PROP_REF_ID
+ );
+ if (sigVerCrypto != null) {
+ config.put(ConfigurationConstants.SIG_VER_PROP_REF_ID, "RefId-" + sigVerCrypto.hashCode());
+ config.put("RefId-" + sigVerCrypto.hashCode(), sigVerCrypto);
+ }
+
+ Crypto decCrypto =
+ loadCrypto(
+ msg,
+ ConfigurationConstants.DEC_PROP_FILE,
+ ConfigurationConstants.DEC_PROP_REF_ID
+ );
+ if (decCrypto != null) {
+ config.put(ConfigurationConstants.DEC_PROP_REF_ID, "RefId-" + decCrypto.hashCode());
+ config.put("RefId-" + decCrypto.hashCode(), decCrypto);
+ }
+ }
+ }
+
+ private void configureCallbackHandler(SoapMessage soapMessage) throws WSSecurityException {
+ Object o = soapMessage.getContextualProperty(SecurityConstants.CALLBACK_HANDLER);
+ if (o instanceof String) {
+ try {
+ o = ClassLoaderUtils.loadClass((String)o, this.getClass()).newInstance();
+ } catch (Exception e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
+ }
+ }
+ if (o instanceof CallbackHandler) {
+ WSSSecurityProperties securityProperties = getSecurityProperties();
+ Map<String, Object> config = getProperties();
+
+ if (securityProperties != null) {
+ securityProperties.setCallbackHandler((CallbackHandler)o);
+ } else {
+ config.put(ConfigurationConstants.PW_CALLBACK_REF, (CallbackHandler)o);
+ }
+ }
+ }
/**
* Create a SoapFault from a WSSecurityException, following the SOAP Message Security
Modified: cxf/branches/wss4j2.0-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/branches/wss4j2.0-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxOutInterceptor.java?rev=1477091&r1=1477090&r2=1477091&view=diff
==============================================================================
--- cxf/branches/wss4j2.0-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxOutInterceptor.java (original)
+++ cxf/branches/wss4j2.0-port/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JStaxOutInterceptor.java Mon Apr 29 14:16:01 2013
@@ -21,6 +21,7 @@ package org.apache.cxf.ws.security.wss4j
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
@@ -35,6 +36,8 @@ import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
+import org.apache.wss4j.common.ConfigurationConstants;
+import org.apache.wss4j.common.crypto.Crypto;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.stax.WSSec;
import org.apache.wss4j.stax.ext.OutboundWSSec;
@@ -53,7 +56,6 @@ public class WSS4JStaxOutInterceptor ext
public static final String OUTPUT_STREAM_HOLDER =
WSS4JStaxOutInterceptor.class.getName() + ".outputstream";
- private final OutboundWSSec outboundWSSec;
private WSS4JStaxOutInterceptorInternal ending;
private boolean mtomEnabled;
@@ -64,15 +66,16 @@ public class WSS4JStaxOutInterceptor ext
getBefore().add(StaxOutInterceptor.class.getName());
ending = createEndingInterceptor();
- outboundWSSec = WSSec.getOutboundWSSec(securityProperties);
+ setSecurityProperties(securityProperties);
}
- /*
- public WSS4JStaxOutInterceptor(Map<String, Object> props) {
- this();
- setProperties(props);
+ public WSS4JStaxOutInterceptor(Map<String, Object> props) throws WSSecurityException {
+ super(props);
+ setPhase(Phase.PRE_STREAM);
+ getBefore().add(StaxOutInterceptor.class.getName());
+
+ ending = createEndingInterceptor();
}
- */
public boolean isAllowMTOM() {
return mtomEnabled;
@@ -117,6 +120,17 @@ public class WSS4JStaxOutInterceptor ext
@SuppressWarnings("unchecked")
final List<SecurityEvent> requestSecurityEvents =
(List<SecurityEvent>) mc.getExchange().get(SecurityEvent.class.getName() + ".in");
+
+ translateProperties(mc);
+ configureProperties(mc);
+
+ OutboundWSSec outboundWSSec = null;
+ if (getSecurityProperties() != null) {
+ outboundWSSec = WSSec.getOutboundWSSec(getSecurityProperties());
+ } else {
+ outboundWSSec = WSSec.getOutboundWSSec(getProperties());
+ }
+
newXMLStreamWriter =
outboundWSSec.processOutMessage(os, encoding, requestSecurityEvents, securityEventListener);
mc.setContent(XMLStreamWriter.class, newXMLStreamWriter);
@@ -142,15 +156,34 @@ public class WSS4JStaxOutInterceptor ext
}
- /*
- private OutboundWSSec createOutSecurityContext(Message message) {
- WSSSecurityProperties properties = new WSSSecurityProperties();
+ private void configureProperties(SoapMessage msg) throws WSSecurityException {
+ Map<String, Object> config = getProperties();
- OutboundWSSec wssec = new OutboundWSSec(properties);
-
- return wssec;
+ // Crypto loading only applies for Map
+ if (config != null) {
+ Crypto sigCrypto =
+ loadCrypto(
+ msg,
+ ConfigurationConstants.SIG_PROP_FILE,
+ ConfigurationConstants.SIG_PROP_REF_ID
+ );
+ if (sigCrypto != null) {
+ config.put(ConfigurationConstants.SIG_PROP_REF_ID, "RefId-" + sigCrypto.hashCode());
+ config.put("RefId-" + sigCrypto.hashCode(), sigCrypto);
+ }
+
+ Crypto encCrypto =
+ loadCrypto(
+ msg,
+ ConfigurationConstants.ENC_PROP_FILE,
+ ConfigurationConstants.ENC_PROP_REF_ID
+ );
+ if (encCrypto != null) {
+ config.put(ConfigurationConstants.ENC_PROP_REF_ID, "RefId-" + encCrypto.hashCode());
+ config.put("RefId-" + encCrypto.hashCode(), encCrypto);
+ }
+ }
}
- */
public final WSS4JStaxOutInterceptorInternal createEndingInterceptor() {
return new WSS4JStaxOutInterceptorInternal();