Author: coheigea
Date: Wed Jan 7 04:34:41 2009
New Revision: 732321
URL: http://svn.apache.org/viewvc?rev=732321&view=rev
Log:
[WSS-154] - A fix for this issue + tests
- The problem was that a custom processor or action could only be specified
via a String
corresponding to the classname, which was only instantiated when
getProcessor/getAction was
called. This is inconvenient if e.g. the object in question is to be
spring-loaded.
- I took a different solution to the proposed patch. The processor map in
WSSConfig can now be
considered as <String, String> or <String,Processor> (similarly for the
action map). When
getProcessor(QName) is called, if the object in the Map is a processor it's
simply returned, if
it's a String, it gets classloaded etc. This is fully backwards compatible.
- So to use a custom processor instance, you can just do e.g.:
WSSConfig cfg = WSSConfig.getNewInstance();
cfg.setProcessor(WSSecurityEngine.SIGNATURE, new wssec.MyProcessor());
final WSSecurityEngine engine = new WSSecurityEngine();
engine.setWssConfig(cfg);
engine.processSecurityHeader(....)
Modified:
webservices/wss4j/trunk/src/org/apache/ws/security/WSSConfig.java
webservices/wss4j/trunk/src/org/apache/ws/security/WSSecurityEngine.java
webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandler.java
webservices/wss4j/trunk/test/wssec/TestWSSecurityUserProcessor.java
Modified: webservices/wss4j/trunk/src/org/apache/ws/security/WSSConfig.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/WSSConfig.java?rev=732321&r1=732320&r2=732321&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/WSSConfig.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/WSSConfig.java Wed Jan
7 04:34:41 2009
@@ -170,7 +170,7 @@
/**
* Set the timestamp precision mode. If set to <code>true</code> then use
- * timestamps with milliseconds, otherwise omit the millisconds. As per XML
+ * timestamps with milliseconds, otherwise omit the milliseconds. As per
XML
* Date/Time specification the default is to include the milliseconds.
*/
protected boolean precisionInMilliSeconds = true;
@@ -198,14 +198,16 @@
protected HashMap jceProvider = new HashMap(10);
/**
- * The known actions. These are initialized from a set of defaults,
- * but the list may be modified via the setAction operation.
+ * The known actions. This map is of the form <Integer, String> or
<Integer, Action>.
+ * The known actions are initialized from a set of defaults,
+ * but the list may be modified via the setAction operations.
*/
private final java.util.Map actionMap = new
java.util.HashMap(DEFAULT_ACTIONS);
/**
- * The known processors. These are initialized from a set of defaults,
- * but the list may be modified via the setProcessor operation.
+ * The known processors. This map is of the form <String, String> or
<String,Processor>.
+ * The known processors are initialized from a set of defaults,
+ * but the list may be modified via the setProcessor operations.
*/
private final java.util.Map processorMap = new
java.util.HashMap(DEFAULT_PROCESSORS);
@@ -220,7 +222,7 @@
/**
* a boolean flag to record whether we have already been statically
- * initialized. This flag prevents repeated and unecessary calls
+ * initialized. This flag prevents repeated and unnecessary calls
* to static initialization code at construction time.
*/
private static boolean staticallyInitialized = false;
@@ -273,8 +275,7 @@
* {...@link #getDefaultWSConfig getDefaultWSConfig()})
*/
public static WSSConfig getNewInstance() {
- WSSConfig config = new WSSConfig();
- return config;
+ return new WSSConfig();
}
/**
@@ -374,13 +375,35 @@
}
/**
- * Associate an action with a specific action code.
+ * Associate an action name with a specific action code.
*
* This operation allows applications to supply their own
* actions for well-known operations.
*/
public String setAction(int code, String action) {
- return (String) actionMap.put(new Integer(code), action);
+ Object previousAction = actionMap.put(new Integer(code), action);
+ if (previousAction instanceof String) {
+ return (String)previousAction;
+ } else if (previousAction instanceof Action){
+ return previousAction.getClass().getName();
+ }
+ return null;
+ }
+
+ /**
+ * Associate an action instance with a specific action code.
+ *
+ * This operation allows applications to supply their own
+ * actions for well-known operations.
+ */
+ public String setAction(int code, Action action) {
+ Object previousAction = actionMap.put(new Integer(code), action);
+ if (previousAction instanceof String) {
+ return (String)previousAction;
+ } else if (previousAction instanceof Action){
+ return previousAction.getClass().getName();
+ }
+ return null;
}
/**
@@ -392,20 +415,23 @@
*/
public Action getAction(int action) throws WSSecurityException {
Integer key = new Integer(action);
- String name = (String) actionMap.get(key);
- if (name == null) {
- throw new WSSecurityException(WSSecurityException.FAILURE,
- "unknownAction", new Object[] { key });
- }
- try {
- return (Action) Loader.loadClass(name).newInstance();
- } catch (Throwable t) {
- if (log.isDebugEnabled()) {
- log.debug(t.getMessage(), t);
+ final Object actionObject = actionMap.get(key);
+
+ if (actionObject instanceof String) {
+ final String name = (String)actionObject;
+ try {
+ return (Action) Loader.loadClass(name).newInstance();
+ } catch (Throwable t) {
+ if (log.isDebugEnabled()) {
+ log.debug(t.getMessage(), t);
+ }
+ throw new WSSecurityException(WSSecurityException.FAILURE,
+ "unableToLoadClass", new Object[] { name }, t);
}
- throw new WSSecurityException(WSSecurityException.FAILURE,
- "unableToLoadClass", new Object[] { name }, t);
- }
+ } else if (actionObject instanceof Action) {
+ return (Action)actionObject;
+ }
+ return null;
}
/**
@@ -414,7 +440,28 @@
* called when processing header elements with the specified type.
*/
public String setProcessor(QName el, String name) {
- return (String) processorMap.put(el, name);
+ Object previousProcessor = processorMap.put(el, name);
+ if (previousProcessor instanceof String) {
+ return (String)previousProcessor;
+ } else if (previousProcessor instanceof Processor){
+ return previousProcessor.getClass().getName();
+ }
+ return null;
+ }
+
+ /**
+ * Associate a SOAP processor instance with a specified SOAP Security
header
+ * element QName. Processors registered under this QName will be
+ * called when processing header elements with the specified type.
+ */
+ public String setProcessor(QName el, Processor processor) {
+ Object previousProcessor = processorMap.put(el, processor);
+ if (previousProcessor instanceof String) {
+ return (String)previousProcessor;
+ } else if (previousProcessor instanceof Processor){
+ return previousProcessor.getClass().getName();
+ }
+ return null;
}
/**
@@ -425,8 +472,9 @@
* specified QName.
*/
public Processor getProcessor(QName el) throws WSSecurityException {
- final String name = (String) processorMap.get(el);
- if (name != null) {
+ final Object processorObject = processorMap.get(el);
+ if (processorObject instanceof String) {
+ final String name = (String)processorObject;
try {
return (Processor) Loader.loadClass(name).newInstance();
} catch (Throwable t) {
@@ -436,7 +484,9 @@
throw new WSSecurityException(WSSecurityException.FAILURE,
"unableToLoadClass", new Object[] { name }, t);
}
- }
+ } else if (processorObject instanceof Processor) {
+ return (Processor)processorObject;
+ }
return null;
}
Modified:
webservices/wss4j/trunk/src/org/apache/ws/security/WSSecurityEngine.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/WSSecurityEngine.java?rev=732321&r1=732320&r2=732321&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/WSSecurityEngine.java
(original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/WSSecurityEngine.java
Wed Jan 7 04:34:41 2009
@@ -58,62 +58,76 @@
/**
* <code>wsse:BinarySecurityToken</code> as defined by WS Security
specification
*/
- public static final QName binaryToken = new QName(WSConstants.WSSE_NS,
WSConstants.BINARY_TOKEN_LN);
+ public static final QName binaryToken =
+ new QName(WSConstants.WSSE_NS, WSConstants.BINARY_TOKEN_LN);
/**
* <code>wsse:UsernameToken</code> as defined by WS Security specification
*/
- public static final QName usernameToken = new QName(WSConstants.WSSE_NS,
WSConstants.USERNAME_TOKEN_LN);
+ public static final QName usernameToken =
+ new QName(WSConstants.WSSE_NS, WSConstants.USERNAME_TOKEN_LN);
/**
* <code>wsu:Timestamp</code> as defined by OASIS WS Security
specification,
*/
- public static final QName timeStamp = new QName(WSConstants.WSU_NS,
WSConstants.TIMESTAMP_TOKEN_LN);
+ public static final QName timeStamp =
+ new QName(WSConstants.WSU_NS, WSConstants.TIMESTAMP_TOKEN_LN);
/**
* <code>wsse11:signatureConfirmation</code> as defined by OASIS WS
Security specification,
*/
- public static final QName signatureConfirmation = new
QName(WSConstants.WSSE11_NS, WSConstants.SIGNATURE_CONFIRMATION_LN);
+ public static final QName signatureConfirmation =
+ new QName(WSConstants.WSSE11_NS,
WSConstants.SIGNATURE_CONFIRMATION_LN);
/**
* <code>ds:Signature</code> as defined by XML Signature specification,
* enhanced by WS Security specification
*/
- public static final QName SIGNATURE = new QName(WSConstants.SIG_NS,
WSConstants.SIG_LN);
+ public static final QName SIGNATURE =
+ new QName(WSConstants.SIG_NS, WSConstants.SIG_LN);
/**
* <code>xenc:EncryptedKey</code> as defined by XML Encryption
specification,
* enhanced by WS Security specification
*/
- public static final QName ENCRYPTED_KEY = new QName(WSConstants.ENC_NS,
WSConstants.ENC_KEY_LN);
+ public static final QName ENCRYPTED_KEY =
+ new QName(WSConstants.ENC_NS, WSConstants.ENC_KEY_LN);
/**
* <code>xenc:EncryptedData</code> as defined by XML Encryption
specification,
* enhanced by WS Security specification
*/
- public static final QName ENCRYPTED_DATA = new QName(WSConstants.ENC_NS,
WSConstants.ENC_DATA_LN);
+ public static final QName ENCRYPTED_DATA =
+ new QName(WSConstants.ENC_NS, WSConstants.ENC_DATA_LN);
/**
* <code>xenc:ReferenceList</code> as defined by XML Encryption
specification,
*/
- public static final QName REFERENCE_LIST = new QName(WSConstants.ENC_NS,
WSConstants.REF_LIST_LN);
+ public static final QName REFERENCE_LIST =
+ new QName(WSConstants.ENC_NS, WSConstants.REF_LIST_LN);
/**
* <code>saml:Assertion</code> as defined by SAML specification
*/
- public static final QName SAML_TOKEN = new QName(WSConstants.SAML_NS,
WSConstants.ASSERTION_LN);
+ public static final QName SAML_TOKEN =
+ new QName(WSConstants.SAML_NS, WSConstants.ASSERTION_LN);
/**
* <code>wsc:DerivedKeyToken</code> as defined by WS-SecureConversation
specification
*/
- public static final QName DERIVED_KEY_TOKEN_05_02 = new
QName(ConversationConstants.WSC_NS_05_02,
ConversationConstants.DERIVED_KEY_TOKEN_LN);
+ public static final QName DERIVED_KEY_TOKEN_05_02 =
+ new QName(ConversationConstants.WSC_NS_05_02,
ConversationConstants.DERIVED_KEY_TOKEN_LN);
/**
* <code>wsc:SecurityContextToken</code> as defined by
WS-SecureConversation specification
*/
- public static final QName SECURITY_CONTEXT_TOKEN_05_02 = new
QName(ConversationConstants.WSC_NS_05_02,
ConversationConstants.SECURITY_CONTEXT_TOKEN_LN);
+ public static final QName SECURITY_CONTEXT_TOKEN_05_02 =
+ new QName(ConversationConstants.WSC_NS_05_02,
ConversationConstants.SECURITY_CONTEXT_TOKEN_LN);
/**
* <code>wsc:DerivedKeyToken</code> as defined by WS-SecureConversation
specification in WS-SX
*/
- public static final QName DERIVED_KEY_TOKEN_05_12 = new
QName(ConversationConstants.WSC_NS_05_12,
ConversationConstants.DERIVED_KEY_TOKEN_LN);
+ public static final QName DERIVED_KEY_TOKEN_05_12 =
+ new QName(ConversationConstants.WSC_NS_05_12,
ConversationConstants.DERIVED_KEY_TOKEN_LN);
/**
- * <code>wsc:SecurityContextToken</code> as defined by
WS-SecureConversation specification in WS-SX
+ * <code>wsc:SecurityContextToken</code> as defined by
WS-SecureConversation specification in
+ * WS-SX
*/
- public static final QName SECURITY_CONTEXT_TOKEN_05_12 = new
QName(ConversationConstants.WSC_NS_05_12,
ConversationConstants.SECURITY_CONTEXT_TOKEN_LN);
+ public static final QName SECURITY_CONTEXT_TOKEN_05_12 =
+ new QName(ConversationConstants.WSC_NS_05_12,
ConversationConstants.SECURITY_CONTEXT_TOKEN_LN);
public WSSecurityEngine() {
}
@@ -171,7 +185,8 @@
* handling of certificates.
* @return a result vector
* @throws WSSecurityException
- * @see WSSecurityEngine#processSecurityHeader(Element securityHeader,
CallbackHandler cb,Crypto sigCrypto, Crypto decCrypto)
+ * @see WSSecurityEngine#processSecurityHeader(Element securityHeader,
CallbackHandler cb,
+ * Crypto sigCrypto, Crypto decCrypto)
*/
public Vector processSecurityHeader(Document doc,
String actor,
@@ -201,7 +216,7 @@
* @return a result vector
* @throws WSSecurityException
* @see WSSecurityEngine#processSecurityHeader(
- * Element securityHeader, CallbackHandler cb,Crypto sigCrypto, Crypto
decCrypto)
+ * Element securityHeader, CallbackHandler cb, Crypto sigCrypto, Crypto
decCrypto)
*/
public Vector processSecurityHeader(Document doc,
String actor,
@@ -223,8 +238,7 @@
Element elem = WSSecurityUtil.getSecurityHeader(doc, actor, sc);
if (elem != null) {
if (doDebug) {
- log.debug("Processing WS-Security header for '" + actor
- + "' actor.");
+ log.debug("Processing WS-Security header for '" + actor + "'
actor.");
}
wsResult = processSecurityHeader(elem, cb, sigCrypto, decCrypto);
}
@@ -313,20 +327,23 @@
wsDocInfo.setProcessor(p);
} else {
/*
- * Add check for a BinarySecurityToken, add info to WSDocInfo.
If BST is
- * found before a Signature token this would speed up (at least
a little
- * bit) the processing of STR Transform.
- */
+ * Add check for a BinarySecurityToken, add info to WSDocInfo.
If BST is
+ * found before a Signature token this would speed up (at
least a little
+ * bit) the processing of STR Transform.
+ */
if (doDebug) {
- log.debug("Unknown Element: " + elem.getLocalName() + " "
+ elem.getNamespaceURI());
+ log.debug(
+ "Unknown Element: " + elem.getLocalName() + " " +
elem.getNamespaceURI()
+ );
}
}
}
if (tlog.isDebugEnabled()) {
t2 = System.currentTimeMillis();
- tlog.debug("processHeader: total " + (t2 - t0) +
- ", prepare " + (t1 - t0) +
- ", handle " + (t2 - t1));
+ tlog.debug(
+ "processHeader: total " + (t2 - t0) + ", prepare " + (t1 - t0)
+ + ", handle " + (t2 - t1)
+ );
}
return returnResults;
}
Modified:
webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandler.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandler.java?rev=732321&r1=732320&r2=732321&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandler.java
(original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandler.java
Wed Jan 7 04:34:41 2009
@@ -249,7 +249,10 @@
protected void doReceiverAction(int doAction, RequestData reqData)
throws WSSecurityException {
- WSSConfig wssConfig = WSSConfig.getNewInstance();
+ WSSConfig wssConfig = reqData.getWssConfig();
+ if (wssConfig == null) {
+ wssConfig = WSSConfig.getNewInstance();
+ }
wssConfig.setEnableSignatureConfirmation(
decodeEnableSignatureConfirmation(reqData)
);
Modified: webservices/wss4j/trunk/test/wssec/TestWSSecurityUserProcessor.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/wssec/TestWSSecurityUserProcessor.java?rev=732321&r1=732320&r2=732321&view=diff
==============================================================================
--- webservices/wss4j/trunk/test/wssec/TestWSSecurityUserProcessor.java
(original)
+++ webservices/wss4j/trunk/test/wssec/TestWSSecurityUserProcessor.java Wed Jan
7 04:34:41 2009
@@ -126,7 +126,7 @@
}
/**
- * Test to see that a custom processor configured through a
+ * Test to see that a custom processor configured through a
* WSSConfig instance is called
*/
public void
@@ -142,7 +142,7 @@
/*
* convert the resulting document into a message first. The
toSOAPMessage()
- * mehtod performs the necessary c14n call to properly set up the
signed
+ * method performs the necessary c14n call to properly set up the
signed
* document and convert it into a SOAP message. After that we extract
it
* as a document again for further processing.
*/
@@ -185,6 +185,64 @@
}
/**
+ * Test to see that a custom processor (object) configured through a
+ * WSSConfig instance is called
+ */
+ public void
+ testCustomUserProcessorObject() throws Exception {
+ WSSecSignature builder = new WSSecSignature();
+ builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e",
"security");
+ builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
+ log.info("Before Signing IS....");
+ Document doc = unsignedEnvelope.getAsDocument();
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+ Document signedDoc = builder.build(doc, crypto, secHeader);
+
+ /*
+ * convert the resulting document into a message first. The
toSOAPMessage()
+ * method performs the necessary c14n call to properly set up the
signed
+ * document and convert it into a SOAP message. After that we extract
it
+ * as a document again for further processing.
+ */
+
+ if (log.isDebugEnabled()) {
+ log.debug("Signed message with IssuerSerial key identifier:");
+ XMLUtils.PrettyElementToWriter(signedDoc.getDocumentElement(), new
PrintWriter(System.out));
+ }
+ Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);
+ if (log.isDebugEnabled()) {
+ log.debug("Signed message with IssuerSerial key identifier(1):");
+
XMLUtils.PrettyElementToWriter(signedMsg.getSOAPEnvelope().getAsDOM(), new
PrintWriter(System.out));
+ }
+ signedDoc = signedMsg.getSOAPEnvelope().getAsDocument();
+ log.info("After Signing IS....");
+ //
+ // Check to make sure we can install/replace and use our own processor
+ //
+ WSSConfig cfg = WSSConfig.getNewInstance();
+ cfg.setProcessor(
+ WSSecurityEngine.SIGNATURE,
+ new wssec.MyProcessor()
+ );
+ final WSSecurityEngine engine = new WSSecurityEngine();
+ engine.setWssConfig(cfg);
+ final java.util.List results =
+ engine.processSecurityHeader(doc, null, null, crypto);
+ boolean found = false;
+ for (final java.util.Iterator pos = results.iterator();
pos.hasNext(); ) {
+ final java.util.Map result = (java.util.Map) pos.next();
+ Object obj = result.get("foo");
+ if (obj != null) {
+ if
(obj.getClass().getName().equals(wssec.MyProcessor.class.getName())) {
+ found = true;
+ }
+ }
+ }
+ assertTrue("Unable to find result from MyProcessor", found);
+ }
+
+ /**
* Test to see that a custom action configured through a
* WSSConfig instance is called
*/
@@ -214,6 +272,35 @@
}
/**
+ * Test to see that a custom action object configured through a
+ * WSSConfig instance is called
+ */
+ public void
+ testCustomActionObject() throws Exception {
+
+ final WSSConfig cfg = WSSConfig.getNewInstance();
+ final int action = 0xDEADF000;
+ cfg.setAction(action, new wssec.MyAction());
+ final RequestData reqData = new RequestData();
+ reqData.setWssConfig(cfg);
+ reqData.setMsgContext(new java.util.TreeMap());
+
+ final java.util.Vector actions = new java.util.Vector();
+ actions.add(new Integer(action));
+ final Document doc = unsignedEnvelope.getAsDocument();
+ MyHandler handler = new MyHandler();
+ reqData.setMsgContext("bread");
+ assertEquals(reqData.getMsgContext(), "bread");
+ handler.doit(
+ action,
+ doc,
+ reqData,
+ actions
+ );
+ assertEquals(reqData.getMsgContext(), "crumb");
+ }
+
+ /**
* a trivial extension of the WSHandler type
*/
public static class MyHandler extends WSHandler {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]