ws-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cohei...@apache.org
Subject svn commit: r1066893 - in /webservices/wss4j/trunk/src: main/java/org/apache/ws/security/ main/java/org/apache/ws/security/message/token/ main/java/org/apache/ws/security/processor/ main/java/org/apache/ws/security/str/ main/java/org/apache/ws/security...
Date Thu, 03 Feb 2011 17:47:44 GMT
Author: coheigea
Date: Thu Feb  3 17:47:43 2011
New Revision: 1066893

URL: http://svn.apache.org/viewvc?rev=1066893&view=rev
Log:
[WSS-266] - Added default validators to WSSConfig and a way of setting them on the processors
 - Added in a test for overriding default validators
 - Changed how UsernameTokens are validated
 - UsernameTokens containing no passwords (i.e. used for Key Derivation) are stored under a new WSConstants.UT_UNKNOWN, and are not dispatched to a CallbackHandler for verification any more


Added:
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/validate/NoOpValidator.java
    webservices/wss4j/trunk/src/test/java/org/apache/ws/security/validate/
    webservices/wss4j/trunk/src/test/java/org/apache/ws/security/validate/ValidatorTest.java
Modified:
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSConstants.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSSConfig.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/UsernameToken.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/BinarySecurityTokenProcessor.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/DerivedKeyTokenProcessor.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/EncryptedDataProcessor.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/EncryptedKeyProcessor.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/Processor.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/ReferenceListProcessor.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SecurityContextTokenProcessor.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SignatureConfirmationProcessor.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SignatureProcessor.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/TimestampProcessor.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/UsernameTokenProcessor.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/DerivedKeyTokenSTRParser.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SignatureSTRParser.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/validate/UsernameTokenValidator.java
    webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/CustomProcessor.java
    webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/UsernamePasswordCallbackHandler.java
    webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/UsernameTokenTest.java

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSConstants.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSConstants.java?rev=1066893&r1=1066892&r2=1066893&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSConstants.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSConstants.java Thu Feb  3 17:47:43 2011
@@ -409,6 +409,7 @@ public class WSConstants {
     public static final int SCT = 0x400; //SecurityContextToken
     public static final int DKT = 0x800; //DerivedKeyToken
     public static final int BST = 0x1000; //BinarySecurityToken
+    public static final int UT_UNKNOWN = 0x2000; // perform UsernameToken
 
     /**
      * Length of UsernameToken derived key used by .NET WSE to sign a message.

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSSConfig.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSSConfig.java?rev=1066893&r1=1066892&r2=1066893&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSSConfig.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSSConfig.java Thu Feb  3 17:47:43 2011
@@ -32,6 +32,7 @@ import org.apache.ws.security.action.Act
 import org.apache.ws.security.processor.Processor;
 import org.apache.ws.security.util.Loader;
 import org.apache.ws.security.util.UUIDGenerator;
+import org.apache.ws.security.validate.Validator;
 
 /**
  * WSSConfig <p/> Carries configuration data so the WSS4J spec compliance can be
@@ -166,6 +167,41 @@ public class WSSConfig {
         }
         DEFAULT_PROCESSORS = java.util.Collections.unmodifiableMap(tmp);
     }
+    
+    /**
+     * The default collection of validators supported by the toolkit
+     */
+    private static final Map<QName, Class<?>> DEFAULT_VALIDATORS;
+    static {
+        final Map<QName, Class<?>> tmp = new HashMap<QName, Class<?>>();
+        try {
+            tmp.put(
+                WSSecurityEngine.SAML_TOKEN,
+                org.apache.ws.security.validate.SamlAssertionValidator.class
+            );
+            tmp.put(
+                WSSecurityEngine.SAML2_TOKEN,
+                org.apache.ws.security.validate.SamlAssertionValidator.class
+            );
+            tmp.put(
+                WSSecurityEngine.SIGNATURE,
+                org.apache.ws.security.validate.SignatureTrustValidator.class
+            );
+            tmp.put(
+                WSSecurityEngine.TIMESTAMP,
+                org.apache.ws.security.validate.TimestampValidator.class
+            );
+            tmp.put(
+                WSSecurityEngine.USERNAME_TOKEN,
+                org.apache.ws.security.validate.UsernameTokenValidator.class
+            );
+        } catch (final Throwable t) {
+            if (log.isDebugEnabled()) {
+                log.debug(t.getMessage(), t);
+            }
+        }
+        DEFAULT_VALIDATORS = java.util.Collections.unmodifiableMap(tmp);
+    }
 
     protected boolean wsiBSPCompliant = false;
 
@@ -278,6 +314,15 @@ public class WSSConfig {
         new HashMap<QName, Object>(DEFAULT_PROCESSORS);
     
     /**
+     * The known validators. This map is of the form <QName, Class<?>> or
+     * <QName, Validator>.
+     * The known validators are initialized from a set of defaults,
+     * but the list may be modified via the setValidator operations.
+     */
+    private final Map<QName, Object> validatorMap = 
+        new HashMap<QName, Object>(DEFAULT_VALIDATORS);
+    
+    /**
      * a static boolean flag that determines whether default JCE providers
      * should be added at the time of construction.
      *
@@ -594,6 +639,65 @@ public class WSSConfig {
     }
     
     /**
+     * Associate a SOAP validator name with a specified SOAP Security header
+     * element QName.  Validators registered under this QName will be
+     * called when processing header elements with the specified type.
+     * 
+     * Please note that the Validator object does NOT get class-loaded per invocation, and so
+     * it is up to the implementing class to ensure that it is thread-safe.
+     */
+    public Class<?> setValidator(QName el, Validator validator) {
+        Object result = validatorMap.put(el, validator);
+        if (result instanceof Class<?>) {
+            return (Class<?>)result;
+        } else if (result instanceof Validator) {
+            return result.getClass();
+        }
+        return null;
+    }
+    
+    /**
+     * Associate a SOAP validator name with a specified SOAP Security header
+     * element QName.  validator registered under this QName will be
+     * called when processing header elements with the specified type.
+     */
+    public Class<?> setValidator(QName el, Class<?> clazz) {
+        Object result = validatorMap.put(el, clazz);
+        if (result instanceof Class<?>) {
+            return (Class<?>)result;
+        } else if (result instanceof Validator) {
+            return result.getClass();
+        }
+        return null;
+    }
+    
+    /**
+     * @return      the SOAP Validator associated with the specified
+     *              QName.  The QName is intended to refer to an element
+     *              in a SOAP security header.  This operation returns
+     *              null if there is no Validator associated with the 
+     *              specified QName.
+     */
+    public Validator getValidator(QName el) throws WSSecurityException {
+        final Object validatorObject = validatorMap.get(el);
+        
+        if (validatorObject instanceof Class<?>) {
+            try {
+                return (Validator)((Class<?>)validatorObject).newInstance();
+            } catch (Throwable t) {
+                if (log.isDebugEnabled()) {
+                    log.debug(t.getMessage(), t);
+                }
+                throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "unableToLoadClass", new Object[] { ((Class<?>)validatorObject).getName() }, t);
+            }
+        } else if (validatorObject instanceof Validator) {
+            return (Validator)validatorObject;
+        }
+        return null;
+    }
+    
+    /**
      * @return      the SOAP processor associated with the specified
      *              QName.  The QName is intended to refer to an element
      *              in a SOAP security header.  This operation returns
@@ -605,7 +709,12 @@ public class WSSConfig {
         
         if (processorObject instanceof Class<?>) {
             try {
-                return (Processor)((Class<?>)processorObject).newInstance();
+                Processor processor = (Processor)((Class<?>)processorObject).newInstance();
+                Validator validator = getValidator(el);
+                if (validator != null) {
+                    processor.setValidator(validator);
+                }
+                return processor;
             } catch (Throwable t) {
                 if (log.isDebugEnabled()) {
                     log.debug(t.getMessage(), t);

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/UsernameToken.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/UsernameToken.java?rev=1066893&r1=1066892&r2=1066893&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/UsernameToken.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/UsernameToken.java Thu Feb  3 17:47:43 2011
@@ -22,6 +22,7 @@ package org.apache.ws.security.message.t
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSPasswordCallback;
 import org.apache.ws.security.WSSecurityException;
 import org.apache.ws.security.WSUsernameTokenPrincipal;
 import org.apache.ws.security.util.DOM2Writer;
@@ -35,7 +36,12 @@ import org.w3c.dom.Text;
 
 import javax.crypto.Mac;
 import javax.crypto.spec.SecretKeySpec;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.xml.namespace.QName;
+
+import java.io.IOException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.Principal;
@@ -479,18 +485,31 @@ public class UsernameToken {
 
     /**
      * Set the raw (plain text) password used to compute secret key.
-     * 
-     * @param newRawPassword the raw password to set
      */
-    public void setRawPassword(String newRawPassword) {
-        rawPassword = newRawPassword;
-    }
-    
-    /**
-     * Get the raw (plain text) password used to compute secret key.
-     */
-    public String getRawPassword() {
-        return rawPassword;
+    public void setRawPassword(CallbackHandler callbackHandler) throws WSSecurityException {
+        WSPasswordCallback pwCb = 
+            new WSPasswordCallback(
+                getName(), getPassword(), getPasswordType(), 
+                WSPasswordCallback.USERNAME_TOKEN_UNKNOWN
+            );
+        try {
+            callbackHandler.handle(new Callback[]{pwCb});
+        } catch (IOException e) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug(e);
+            }
+            throw new WSSecurityException(
+                WSSecurityException.FAILED_AUTHENTICATION, null, null, e
+            );
+        } catch (UnsupportedCallbackException e) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug(e);
+            }
+            throw new WSSecurityException(
+                WSSecurityException.FAILED_AUTHENTICATION, null, null, e
+            );
+        }
+        rawPassword = pwCb.getPassword();
     }
     
     /**
@@ -672,7 +691,6 @@ public class UsernameToken {
             key = P_hash(password, seed, mac, keylen);
 
             if (LOG.isDebugEnabled()) {
-                LOG.debug("password   :" + Base64.encode(password));
                 LOG.debug("label      :" + Base64.encode(label));
                 LOG.debug("nonce      :" + Base64.encode(nonce));
                 LOG.debug("created    :" + Base64.encode(created));
@@ -771,6 +789,9 @@ public class UsernameToken {
      * @throws WSSecurityException
      */
     public byte[] getDerivedKey() throws WSSecurityException {
+        if (rawPassword == null) {
+            throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);
+        }
         int iteration = getIteration();
         byte[] salt = getSalt();
         if (passwordsAreEncoded) {

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/BinarySecurityTokenProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/BinarySecurityTokenProcessor.java?rev=1066893&r1=1066892&r2=1066893&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/BinarySecurityTokenProcessor.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/BinarySecurityTokenProcessor.java Thu Feb  3 17:47:43 2011
@@ -28,6 +28,7 @@ import org.apache.ws.security.components
 import org.apache.ws.security.message.token.BinarySecurity;
 import org.apache.ws.security.message.token.PKIPathSecurity;
 import org.apache.ws.security.message.token.X509Security;
+import org.apache.ws.security.validate.Validator;
 import org.w3c.dom.Element;
 
 import java.security.cert.X509Certificate;
@@ -38,6 +39,14 @@ import javax.security.auth.callback.Call
  * Processor implementation to handle wsse:BinarySecurityToken elements
  */
 public class BinarySecurityTokenProcessor implements Processor {
+    
+    /**
+     * Set a Validator implementation to validate the credential
+     * @param validator the Validator implementation to set
+     */
+    public void setValidator(Validator validator) {
+        // not used
+    }
 
     /**
      * {@inheritDoc}

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/DerivedKeyTokenProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/DerivedKeyTokenProcessor.java?rev=1066893&r1=1066892&r2=1066893&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/DerivedKeyTokenProcessor.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/DerivedKeyTokenProcessor.java Thu Feb  3 17:47:43 2011
@@ -28,6 +28,7 @@ import org.apache.ws.security.components
 import org.apache.ws.security.message.token.DerivedKeyToken;
 import org.apache.ws.security.str.DerivedKeyTokenSTRParser;
 import org.apache.ws.security.str.STRParser;
+import org.apache.ws.security.validate.Validator;
 import org.w3c.dom.Element;
 
 import javax.security.auth.callback.CallbackHandler;
@@ -40,6 +41,14 @@ import java.util.List;
  * @author Ruchith Fernando (ruchith.fernando@gmail.com)
  */
 public class DerivedKeyTokenProcessor implements Processor {
+    
+    /**
+     * Set a Validator implementation to validate the credential
+     * @param validator the Validator implementation to set
+     */
+    public void setValidator(Validator validator) {
+        // not used
+    }
 
     public List<WSSecurityEngineResult> handleToken(
         Element elem, 

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/EncryptedDataProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/EncryptedDataProcessor.java?rev=1066893&r1=1066892&r2=1066893&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/EncryptedDataProcessor.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/EncryptedDataProcessor.java Thu Feb  3 17:47:43 2011
@@ -26,6 +26,7 @@ import org.apache.ws.security.WSSecurity
 import org.apache.ws.security.WSSecurityException;
 import org.apache.ws.security.components.crypto.Crypto;
 import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.ws.security.validate.Validator;
 import org.apache.xml.security.encryption.XMLCipher;
 import org.apache.xml.security.encryption.XMLEncryptionException;
 import org.w3c.dom.Element;
@@ -44,6 +45,14 @@ import java.util.List;
  */
 public class EncryptedDataProcessor implements Processor {
     
+    /**
+     * Set a Validator implementation to validate the credential
+     * @param validator the Validator implementation to set
+     */
+    public void setValidator(Validator validator) {
+        // not used
+    }
+    
     public List<WSSecurityEngineResult> handleToken(
         Element elem, 
         Crypto crypto, 

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/EncryptedKeyProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/EncryptedKeyProcessor.java?rev=1066893&r1=1066892&r2=1066893&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/EncryptedKeyProcessor.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/EncryptedKeyProcessor.java Thu Feb  3 17:47:43 2011
@@ -34,6 +34,7 @@ import org.apache.ws.security.str.Encryp
 import org.apache.ws.security.str.STRParser;
 import org.apache.ws.security.util.Base64;
 import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.ws.security.validate.Validator;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -56,6 +57,14 @@ import java.util.List;
 public class EncryptedKeyProcessor implements Processor {
     private static Log log = LogFactory.getLog(EncryptedKeyProcessor.class.getName());
     
+    /**
+     * Set a Validator implementation to validate the credential
+     * @param validator the Validator implementation to set
+     */
+    public void setValidator(Validator validator) {
+        // not used
+    }
+    
     public List<WSSecurityEngineResult> handleToken(
         Element elem, 
         Crypto crypto, 

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/Processor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/Processor.java?rev=1066893&r1=1066892&r2=1066893&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/Processor.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/Processor.java Thu Feb  3 17:47:43 2011
@@ -24,6 +24,7 @@ import org.apache.ws.security.WSSConfig;
 import org.apache.ws.security.WSSecurityEngineResult;
 import org.apache.ws.security.WSSecurityException;
 import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.validate.Validator;
 import org.w3c.dom.Element;
 
 import java.util.List;
@@ -40,4 +41,10 @@ public interface Processor {
         WSSConfig config
     ) throws WSSecurityException;
     
+    /**
+     * Set a Validator implementation to validate the credential
+     * @param validator the Validator implementation to set
+     */
+    public void setValidator(Validator validator);
+    
 }

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/ReferenceListProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/ReferenceListProcessor.java?rev=1066893&r1=1066892&r2=1066893&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/ReferenceListProcessor.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/ReferenceListProcessor.java Thu Feb  3 17:47:43 2011
@@ -39,6 +39,7 @@ import org.apache.ws.security.components
 import org.apache.ws.security.str.STRParser;
 import org.apache.ws.security.str.SecurityTokenRefSTRParser;
 import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.ws.security.validate.Validator;
 import org.apache.xml.security.encryption.XMLCipher;
 import org.apache.xml.security.encryption.XMLEncryptionException;
 import org.w3c.dom.Attr;
@@ -49,6 +50,14 @@ import org.w3c.dom.Node;
 public class ReferenceListProcessor implements Processor {
     private static Log log = 
         LogFactory.getLog(ReferenceListProcessor.class.getName());
+    
+    /**
+     * Set a Validator implementation to validate the credential
+     * @param validator the Validator implementation to set
+     */
+    public void setValidator(Validator validator) {
+        // not used
+    }
 
     public List<WSSecurityEngineResult> handleToken(
         Element elem, 

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java?rev=1066893&r1=1066892&r2=1066893&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java Thu Feb  3 17:47:43 2011
@@ -43,6 +43,14 @@ public class SAMLTokenProcessor implemen
     
     private Validator validator = new SamlAssertionValidator();
     
+    /**
+     * Set a Validator implementation to validate the credential
+     * @param validator the Validator implementation to set
+     */
+    public void setValidator(Validator validator) {
+        this.validator = validator;
+    }
+    
     public List<WSSecurityEngineResult> handleToken(
         Element elem, 
         Crypto crypto,

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SecurityContextTokenProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SecurityContextTokenProcessor.java?rev=1066893&r1=1066892&r2=1066893&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SecurityContextTokenProcessor.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SecurityContextTokenProcessor.java Thu Feb  3 17:47:43 2011
@@ -27,6 +27,7 @@ import org.apache.ws.security.WSSecurity
 import org.apache.ws.security.WSSecurityException;
 import org.apache.ws.security.components.crypto.Crypto;
 import org.apache.ws.security.message.token.SecurityContextToken;
+import org.apache.ws.security.validate.Validator;
 import org.w3c.dom.Element;
 
 import javax.security.auth.callback.Callback;
@@ -42,6 +43,14 @@ import java.io.IOException;
  * @author Ruchith Fernando (ruchith.fernando@gmail.com)
  */
 public class SecurityContextTokenProcessor implements Processor {
+    
+    /**
+     * Set a Validator implementation to validate the credential
+     * @param validator the Validator implementation to set
+     */
+    public void setValidator(Validator validator) {
+        // not used
+    }
 
     public List<WSSecurityEngineResult> handleToken(
         Element elem, 

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SignatureConfirmationProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SignatureConfirmationProcessor.java?rev=1066893&r1=1066892&r2=1066893&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SignatureConfirmationProcessor.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SignatureConfirmationProcessor.java Thu Feb  3 17:47:43 2011
@@ -28,6 +28,7 @@ import org.apache.ws.security.WSSecurity
 import org.apache.ws.security.WSSecurityException;
 import org.apache.ws.security.components.crypto.Crypto;
 import org.apache.ws.security.message.token.SignatureConfirmation;
+import org.apache.ws.security.validate.Validator;
 import org.w3c.dom.Element;
 
 import java.util.List;
@@ -35,6 +36,14 @@ import javax.security.auth.callback.Call
 
 public class SignatureConfirmationProcessor implements Processor {
     private static Log log = LogFactory.getLog(SignatureConfirmationProcessor.class.getName());
+    
+    /**
+     * Set a Validator implementation to validate the credential
+     * @param validator the Validator implementation to set
+     */
+    public void setValidator(Validator validator) {
+        // not used
+    }
 
     public List<WSSecurityEngineResult> handleToken(
         Element elem, 

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SignatureProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SignatureProcessor.java?rev=1066893&r1=1066892&r2=1066893&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SignatureProcessor.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SignatureProcessor.java Thu Feb  3 17:47:43 2011
@@ -79,6 +79,14 @@ public class SignatureProcessor implemen
     private KeyInfoFactory keyInfoFactory = KeyInfoFactory.getInstance("DOM");
     private Validator validator = new SignatureTrustValidator();
     
+    /**
+     * Set a Validator implementation to validate the credential
+     * @param validator the Validator implementation to set
+     */
+    public void setValidator(Validator validator) {
+        this.validator = validator;
+    }
+    
     public List<WSSecurityEngineResult> handleToken(
         Element elem, 
         Crypto crypto, 

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/TimestampProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/TimestampProcessor.java?rev=1066893&r1=1066892&r2=1066893&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/TimestampProcessor.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/TimestampProcessor.java Thu Feb  3 17:47:43 2011
@@ -39,6 +39,14 @@ import javax.security.auth.callback.Call
 public class TimestampProcessor implements Processor {
     private static Log log = LogFactory.getLog(TimestampProcessor.class.getName());
     private Validator validator = new TimestampValidator();
+    
+    /**
+     * Set a Validator implementation to validate the credential
+     * @param validator the Validator implementation to set
+     */
+    public void setValidator(Validator validator) {
+        this.validator = validator;
+    }
 
     public List<WSSecurityEngineResult> handleToken(
         Element elem, 

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/UsernameTokenProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/UsernameTokenProcessor.java?rev=1066893&r1=1066892&r2=1066893&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/UsernameTokenProcessor.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/UsernameTokenProcessor.java Thu Feb  3 17:47:43 2011
@@ -41,6 +41,14 @@ public class UsernameTokenProcessor impl
     private static Log log = LogFactory.getLog(UsernameTokenProcessor.class.getName());
     
     private Validator validator = new UsernameTokenValidator();
+    
+    /**
+     * Set a Validator implementation to validate the credential
+     * @param validator the Validator implementation to set
+     */
+    public void setValidator(Validator validator) {
+        this.validator = validator;
+    }
 
     public List<WSSecurityEngineResult> handleToken(
         Element elem, Crypto crypto, Crypto decCrypto, CallbackHandler cb, 
@@ -61,8 +69,12 @@ public class UsernameTokenProcessor impl
         principal.setCreatedTime(token.getCreated());
         principal.setPasswordType(token.getPasswordType());
         
+        int action = WSConstants.UT;
+        if (token.getPassword() == null) { 
+            action = WSConstants.UT_UNKNOWN;
+        }
         WSSecurityEngineResult result = 
-            new WSSecurityEngineResult(WSConstants.UT, token, principal);
+            new WSSecurityEngineResult(action, token, principal);
         result.put(WSSecurityEngineResult.TAG_ID, token.getID());
         wsDocInfo.addTokenElement(elem);
         wsDocInfo.addResult(result);

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/DerivedKeyTokenSTRParser.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/DerivedKeyTokenSTRParser.java?rev=1066893&r1=1066892&r2=1066893&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/DerivedKeyTokenSTRParser.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/DerivedKeyTokenSTRParser.java Thu Feb  3 17:47:43 2011
@@ -91,9 +91,10 @@ public class DerivedKeyTokenSTRParser im
         
         if (result != null) {
             int action = ((Integer)result.get(WSSecurityEngineResult.TAG_ACTION)).intValue();
-            if (WSConstants.UT == action) {
+            if (WSConstants.UT_UNKNOWN == action || WSConstants.UT == action) {
                 UsernameToken usernameToken = 
                     (UsernameToken)result.get(WSSecurityEngineResult.TAG_USERNAME_TOKEN);
+                usernameToken.setRawPassword(cb);
                 secretKey = usernameToken.getDerivedKey();
             } else if (WSConstants.ENCR == action) {
                 secretKey = (byte[])result.get(WSSecurityEngineResult.TAG_SECRET);

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SignatureSTRParser.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SignatureSTRParser.java?rev=1066893&r1=1066892&r2=1066893&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SignatureSTRParser.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SignatureSTRParser.java Thu Feb  3 17:47:43 2011
@@ -146,10 +146,11 @@ public class SignatureSTRParser implemen
                 }
             } else {
                 int action = ((Integer)result.get(WSSecurityEngineResult.TAG_ACTION)).intValue();
-                if (WSConstants.UT == action) {
+                if (WSConstants.UT_UNKNOWN == action || WSConstants.UT == action) {
                     UsernameToken usernameToken = 
                         (UsernameToken)result.get(WSSecurityEngineResult.TAG_USERNAME_TOKEN);
 
+                    usernameToken.setRawPassword(cb);
                     if (usernameToken.isDerivedKey()) {
                         secretKey = usernameToken.getDerivedKey();
                     } else {

Added: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/validate/NoOpValidator.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/validate/NoOpValidator.java?rev=1066893&view=auto
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/validate/NoOpValidator.java (added)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/validate/NoOpValidator.java Thu Feb  3 17:47:43 2011
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.ws.security.validate;
+
+import javax.security.auth.callback.CallbackHandler;
+
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+
+/**
+ * This class does not do any Validation at all.
+ */
+public class NoOpValidator implements Validator {
+    
+    /**
+     * Validate the credential argument. 
+     * 
+     * @param credential the Credential to be validated
+     * @throws WSSecurityException on a failed validation
+     */
+    public void validate(Credential credential) throws WSSecurityException {
+        //
+    }
+    
+    /**
+     * Set a WSSConfig instance used to extract configured options used to 
+     * validate credentials. This method is not currently used for this implementation.
+     * @param wssConfig a WSSConfig instance
+     */
+    public void setWSSConfig(WSSConfig wssConfig) {
+        //
+    }
+    
+    /**
+     * Set a Crypto instance used to validate credentials. This method is not currently
+     * used for this implementation.
+     * @param crypto a Crypto instance used to validate credentials
+     */
+    public void setCrypto(Crypto crypto) {
+        //
+    }
+    
+    /**
+     * Set a CallbackHandler instance used to validate credentials. This method is not 
+     * currently used for this implementation.
+     * @param callbackHandler a CallbackHandler instance used to validate credentials
+     */
+    public void setCallbackHandler(CallbackHandler callbackHandler) {
+        //
+    }
+   
+}

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/validate/UsernameTokenValidator.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/validate/UsernameTokenValidator.java?rev=1066893&r1=1066892&r2=1066893&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/validate/UsernameTokenValidator.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/validate/UsernameTokenValidator.java Thu Feb  3 17:47:43 2011
@@ -43,19 +43,18 @@ public class UsernameTokenValidator impl
     
     private static Log log = LogFactory.getLog(UsernameTokenValidator.class.getName());
     
-    private WSSConfig wssConfig;
-    private CallbackHandler callbackHandler;
+    protected WSSConfig wssConfig;
+    protected CallbackHandler callbackHandler;
     
     /**
      * Validate the credential argument. It must contain a non-null UsernameToken. A 
      * CallbackHandler implementation is also required to be set.
      * 
-     * If the password type is either digest or plaintext, or if the password is not
-     * null and the password type is null or empty, it extracts a password from the 
+     * If the password type is either digest or plaintext, it extracts a password from the 
      * CallbackHandler and then compares the passwords appropriately.
      * 
-     * If the password type is non-standard, or if the password is null, it delegates
-     * the authentication to the CallbackHandler.
+     * If the password is null it queries a hook to allow the user to validate UsernameTokens
+     * of this type. 
      * 
      * @param credential the Credential to be validated
      * @throws WSSecurityException on a failed validation
@@ -64,9 +63,6 @@ public class UsernameTokenValidator impl
         if (credential == null || credential.getUsernametoken() == null) {
             throw new WSSecurityException(WSSecurityException.FAILURE, "noCredential");
         }
-        if (callbackHandler == null) {
-            throw new WSSecurityException(WSSecurityException.FAILURE, "noCallback");
-        }
         
         boolean handleCustomPasswordTypes = false;
         boolean passwordsAreEncoded = false;
@@ -80,13 +76,9 @@ public class UsernameTokenValidator impl
         UsernameToken usernameToken = credential.getUsernametoken();
         usernameToken.setPasswordsAreEncoded(passwordsAreEncoded);
         
-        String user = usernameToken.getName();
-        String password = usernameToken.getPassword();
-        String nonce = usernameToken.getNonce();
-        String createdTime = usernameToken.getCreated();
         String pwType = usernameToken.getPasswordType();
         if (log.isDebugEnabled()) {
-            log.debug("UsernameToken user " + user);
+            log.debug("UsernameToken user " + usernameToken.getName());
             log.debug("UsernameToken password type " + pwType);
         }
         
@@ -103,80 +95,23 @@ public class UsernameTokenValidator impl
         // callback handler and compare directly. If the UsernameToken is of some unknown type,
         // then delegate authentication to the callback handler
         //
-        if (usernameToken.isHashed() || WSConstants.PASSWORD_TEXT.equals(pwType) 
+        String password = usernameToken.getPassword();
+        if (usernameToken.isHashed()) {
+            verifyDigestPassword(usernameToken);
+        } else if (WSConstants.PASSWORD_TEXT.equals(pwType)
             || (password != null && (pwType == null || "".equals(pwType.trim())))) {
-            WSPasswordCallback pwCb = 
-                new WSPasswordCallback(user, null, pwType, WSPasswordCallback.USERNAME_TOKEN);
-            try {
-                callbackHandler.handle(new Callback[]{pwCb});
-            } catch (IOException e) {
-                if (log.isDebugEnabled()) {
-                    log.debug(e);
-                }
-                throw new WSSecurityException(
-                    WSSecurityException.FAILED_AUTHENTICATION, null, null, e
-                );
-            } catch (UnsupportedCallbackException e) {
-                if (log.isDebugEnabled()) {
-                    log.debug(e);
-                }
-                throw new WSSecurityException(
-                    WSSecurityException.FAILED_AUTHENTICATION, null, null, e
-                );
-            }
-            String origPassword = pwCb.getPassword();
-            if (origPassword == null) {
-                if (log.isDebugEnabled()) {
-                    log.debug("Callback supplied no password for: " + user);
-                }
-                throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);
-            }
-            if (usernameToken.isHashed()) {
-                String passDigest;
-                if (passwordsAreEncoded) {
-                    passDigest = UsernameToken.doPasswordDigest(nonce, createdTime, Base64.decode(origPassword));
-                } else {
-                    passDigest = UsernameToken.doPasswordDigest(nonce, createdTime, origPassword);
-                }
-                if (!passDigest.equals(password)) {
-                    throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);
-                }
-            } else {
-                if (!origPassword.equals(password)) {
-                    throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);
-                }
-            }
-            usernameToken.setRawPassword(origPassword);
-        } else {
-            if (pwType != null && !handleCustomPasswordTypes) {
+            verifyPlaintextPassword(usernameToken);
+        } else if (password != null) {
+            if (!handleCustomPasswordTypes) {
                 if (log.isDebugEnabled()) {
                     log.debug("Authentication failed as handleCustomUsernameTokenTypes is false");
                 }
                 throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);
             }
-            WSPasswordCallback pwCb = new WSPasswordCallback(user, password,
-                    pwType, WSPasswordCallback.USERNAME_TOKEN_UNKNOWN);
-            try {
-                callbackHandler.handle(new Callback[]{pwCb});
-            } catch (IOException e) {
-                if (log.isDebugEnabled()) {
-                    log.debug(e);
-                }
-                throw new WSSecurityException(
-                    WSSecurityException.FAILED_AUTHENTICATION, null, null, e
-                );
-            } catch (UnsupportedCallbackException e) {
-                if (log.isDebugEnabled()) {
-                    log.debug(e);
-                }
-                throw new WSSecurityException(
-                    WSSecurityException.FAILED_AUTHENTICATION, null, null, e
-                );
-            }
-            String origPassword = pwCb.getPassword();
-            usernameToken.setRawPassword(origPassword);
+            verifyCustomPassword(usernameToken);
+        } else {
+            verifyUnknownPassword(usernameToken);
         }
-        
     }
     
     /**
@@ -205,5 +140,105 @@ public class UsernameTokenValidator impl
     public void setCallbackHandler(CallbackHandler callbackHandler) {
         this.callbackHandler = callbackHandler;
     }
+    
+    /**
+     * Verify a UsernameToken containing a password of some unknown (but specified) password
+     * type. It does this by querying a CallbackHandler instance to obtain a password for the
+     * given username, and then comparing it against the received password.
+     * This method currently uses the same logic as the verifyPlaintextPassword case, but it in
+     * a separate protected method to allow users to override the validation of the custom 
+     * password type specific case.
+     * @param usernameToken The UsernameToken instance to verify
+     * @throws WSSecurityException on a failed authentication.
+     */
+    protected void verifyCustomPassword(UsernameToken usernameToken) throws WSSecurityException {
+        verifyPlaintextPassword(usernameToken);
+    }
+    
+    /**
+     * Verify a UsernameToken containing a plaintext password. It does this by querying a 
+     * CallbackHandler instance to obtain a password for the given username, and then comparing
+     * it against the received password.
+     * This method currently uses the same logic as the verifyDigestPassword case, but it in
+     * a separate protected method to allow users to override the validation of the plaintext 
+     * password specific case.
+     * @param usernameToken The UsernameToken instance to verify
+     * @throws WSSecurityException on a failed authentication.
+     */
+    protected void verifyPlaintextPassword(UsernameToken usernameToken) throws WSSecurityException {
+        verifyDigestPassword(usernameToken);
+    }
+    
+    /**
+     * Verify a UsernameToken containing a password digest. It does this by querying a 
+     * CallbackHandler instance to obtain a password for the given username, and then comparing
+     * it against the received password.
+     * @param usernameToken The UsernameToken instance to verify
+     * @throws WSSecurityException on a failed authentication.
+     */
+    protected void verifyDigestPassword(UsernameToken usernameToken) throws WSSecurityException {
+        if (callbackHandler == null) {
+            throw new WSSecurityException(WSSecurityException.FAILURE, "noCallback");
+        }
+        
+        String user = usernameToken.getName();
+        String password = usernameToken.getPassword();
+        String nonce = usernameToken.getNonce();
+        String createdTime = usernameToken.getCreated();
+        String pwType = usernameToken.getPasswordType();
+        boolean passwordsAreEncoded = usernameToken.getPasswordsAreEncoded();
+        
+        WSPasswordCallback pwCb = 
+            new WSPasswordCallback(user, null, pwType, WSPasswordCallback.USERNAME_TOKEN);
+        try {
+            callbackHandler.handle(new Callback[]{pwCb});
+        } catch (IOException e) {
+            if (log.isDebugEnabled()) {
+                log.debug(e);
+            }
+            throw new WSSecurityException(
+                WSSecurityException.FAILED_AUTHENTICATION, null, null, e
+            );
+        } catch (UnsupportedCallbackException e) {
+            if (log.isDebugEnabled()) {
+                log.debug(e);
+            }
+            throw new WSSecurityException(
+                WSSecurityException.FAILED_AUTHENTICATION, null, null, e
+            );
+        }
+        String origPassword = pwCb.getPassword();
+        if (origPassword == null) {
+            if (log.isDebugEnabled()) {
+                log.debug("Callback supplied no password for: " + user);
+            }
+            throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);
+        }
+        if (usernameToken.isHashed()) {
+            String passDigest;
+            if (passwordsAreEncoded) {
+                passDigest = UsernameToken.doPasswordDigest(nonce, createdTime, Base64.decode(origPassword));
+            } else {
+                passDigest = UsernameToken.doPasswordDigest(nonce, createdTime, origPassword);
+            }
+            if (!passDigest.equals(password)) {
+                throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);
+            }
+        } else {
+            if (!origPassword.equals(password)) {
+                throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);
+            }
+        }
+    }
+    
+    /**
+     * Verify a UsernameToken containing no password. This does nothing - but is in a separate
+     * method to allow the end-user to override validation easily. 
+     * @param usernameToken The UsernameToken instance to verify
+     * @throws WSSecurityException on a failed authentication.
+     */
+    protected void verifyUnknownPassword(UsernameToken usernameToken) throws WSSecurityException {
+        //
+    }
    
 }

Modified: webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/CustomProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/CustomProcessor.java?rev=1066893&r1=1066892&r2=1066893&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/CustomProcessor.java (original)
+++ webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/CustomProcessor.java Thu Feb  3 17:47:43 2011
@@ -22,6 +22,7 @@ package org.apache.ws.security.common;
 import org.apache.ws.security.components.crypto.Crypto;
 import org.apache.ws.security.message.token.SecurityContextToken;
 import org.apache.ws.security.processor.Processor;
+import org.apache.ws.security.validate.Validator;
 import org.apache.ws.security.WSConstants;
 import org.apache.ws.security.WSDocInfo;
 import org.apache.ws.security.WSSConfig;
@@ -50,4 +51,12 @@ public class CustomProcessor implements 
         result.put("foo", this);
         return java.util.Collections.singletonList(result);
     }
+    
+    /**
+     * Set a Validator implementation to validate the credential
+     * @param validator the Validator implementation to set
+     */
+    public void setValidator(Validator validator) {
+        // 
+    }
 }

Modified: webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/UsernamePasswordCallbackHandler.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/UsernamePasswordCallbackHandler.java?rev=1066893&r1=1066892&r2=1066893&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/UsernamePasswordCallbackHandler.java (original)
+++ webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/UsernamePasswordCallbackHandler.java Thu Feb  3 17:47:43 2011
@@ -55,8 +55,6 @@ public class UsernamePasswordCallbackHan
                     String password = users.get(pc.getIdentifier());
                     if (password != null) {
                         pc.setPassword(password);
-                    } else {
-                        throw new IOException("Authentication failed");
                     }
                     break;
                 }

Modified: webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/UsernameTokenTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/UsernameTokenTest.java?rev=1066893&r1=1066892&r2=1066893&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/UsernameTokenTest.java (original)
+++ webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/UsernameTokenTest.java Thu Feb  3 17:47:43 2011
@@ -21,6 +21,7 @@ package org.apache.ws.security.message;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSSecurityEngineResult;
 import org.apache.ws.security.WSSecurityException;
 import org.apache.ws.security.WSPasswordCallback;
 import org.apache.ws.security.WSSecurityEngine;
@@ -34,6 +35,7 @@ import org.apache.ws.security.handler.Re
 import org.apache.ws.security.handler.WSHandlerConstants;
 import org.apache.ws.security.message.token.UsernameToken;
 import org.apache.ws.security.util.Base64;
+import org.apache.ws.security.util.WSSecurityUtil;
 import org.w3c.dom.Document;
 
 import javax.security.auth.callback.Callback;
@@ -41,6 +43,7 @@ import javax.security.auth.callback.Call
 import javax.security.auth.callback.UnsupportedCallbackException;
 import java.io.IOException;
 import java.security.MessageDigest;
+import java.util.List;
 
 /**
  * WS-Security Test Case for UsernameTokens.
@@ -192,7 +195,7 @@ public class UsernameTokenTest extends o
         LOG.info("After adding UsernameToken PW Digest....");
         try {
             verify(signedDoc);
-            throw new Exception("Failure expected on a bad username");
+            fail("Failure expected on a bad username");
         } catch (WSSecurityException ex) {
             String message = ex.getMessage();
             assertTrue(message.indexOf("badusername") == -1);
@@ -223,7 +226,7 @@ public class UsernameTokenTest extends o
         LOG.info("After adding UsernameToken PW Digest....");
         try {
             verify(signedDoc);
-            throw new Exception("Failure expected on a bad password digest");
+            fail("Failure expected on a bad password digest");
         } catch (WSSecurityException ex) {
             assertTrue(ex.getErrorCode() == WSSecurityException.FAILED_AUTHENTICATION);
             // expected
@@ -304,7 +307,7 @@ public class UsernameTokenTest extends o
         
         try {
             verify(signedDoc);
-            throw new Exception("Failure expected on a bad password text");
+            fail("Failure expected on a bad password text");
         } catch (WSSecurityException ex) {
             assertTrue(ex.getErrorCode() == WSSecurityException.FAILED_AUTHENTICATION);
             // expected
@@ -344,7 +347,7 @@ public class UsernameTokenTest extends o
         }
         try {
             verify(doc);
-            throw new Exception("Failure expected on no password");
+            fail("Failure expected on no password");
         } catch (WSSecurityException ex) {
             assertTrue(ex.getErrorCode() == WSSecurityException.FAILED_AUTHENTICATION);
             // expected
@@ -369,13 +372,13 @@ public class UsernameTokenTest extends o
                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
             LOG.debug(outputString);
         }
-        try {
-            verify(signedDoc);
-            throw new Exception("Failure expected on no password");
-        } catch (WSSecurityException ex) {
-            assertTrue(ex.getErrorCode() == WSSecurityException.FAILED_AUTHENTICATION);
-            // expected
-        }
+        
+        List<WSSecurityEngineResult> results = verify(signedDoc);
+        WSSecurityEngineResult actionResult =
+            WSSecurityUtil.fetchActionResult(results, WSConstants.UT_UNKNOWN);
+        UsernameToken receivedToken = 
+            (UsernameToken) actionResult.get(WSSecurityEngineResult.TAG_USERNAME_TOKEN);
+        assertTrue(receivedToken != null);
     }
     
     /**
@@ -416,44 +419,14 @@ public class UsernameTokenTest extends o
     }
     
     /**
-     * Test with a null token type. This will fail as the default is to reject custom
-     * token types.
-     */
-    @org.junit.Test
-    public void testUsernameTokenCustomFail() throws Exception {
-        WSSecUsernameToken builder = new WSSecUsernameToken();
-        builder.setPasswordType(null);
-        builder.setUserInfo("wernerd", null);
-        
-        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
-        WSSecHeader secHeader = new WSSecHeader();
-        secHeader.insertSecurityHeader(doc);
-        Document signedDoc = builder.build(doc, secHeader);
-        
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Message with UserNameToken PW Text:");
-            String outputString = 
-                org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
-            LOG.debug(outputString);
-        }
-        try {
-            secEngine.processSecurityHeader(signedDoc, null, this, null);
-            throw new Exception("Custom token types are not permitted");
-        } catch (WSSecurityException ex) {
-            assertTrue(ex.getErrorCode() == WSSecurityException.FAILED_AUTHENTICATION);
-            // expected
-        }
-    }
-    
-    /**
      * Test with a non-standard token type. This will fail as the default is to reject custom
      * token types.
      */
     @org.junit.Test
-    public void testUsernameTokenCustomFail2() throws Exception {
+    public void testUsernameTokenCustomFail() throws Exception {
         WSSecUsernameToken builder = new WSSecUsernameToken();
         builder.setPasswordType("RandomType");
-        builder.setUserInfo("customUser", "randomPass");
+        builder.setUserInfo("wernerd", "verySecret");
         
         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
         WSSecHeader secHeader = new WSSecHeader();
@@ -468,7 +441,7 @@ public class UsernameTokenTest extends o
         }
         try {
             secEngine.processSecurityHeader(signedDoc, null, this, null);
-            throw new Exception("Custom token types are not permitted");
+            fail("Custom token types are not permitted");
         } catch (WSSecurityException ex) {
             assertTrue(ex.getErrorCode() == WSSecurityException.FAILED_AUTHENTICATION);
             // expected
@@ -483,7 +456,7 @@ public class UsernameTokenTest extends o
     public void testUsernameTokenCustomPass() throws Exception {
         WSSecUsernameToken builder = new WSSecUsernameToken();
         builder.setPasswordType("RandomType");
-        builder.setUserInfo("customUser", "randomPass");
+        builder.setUserInfo("wernerd", "verySecret");
 
         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
         WSSecHeader secHeader = new WSSecHeader();
@@ -503,7 +476,7 @@ public class UsernameTokenTest extends o
         WSSConfig cfg = WSSConfig.getNewInstance();
         cfg.setHandleCustomPasswordTypes(true);
         secEngine.setWssConfig(cfg);
-        secEngine.processSecurityHeader(signedDoc, null, this, null);
+        verify(signedDoc);
         
         //
         // Go back to default for other tests
@@ -549,7 +522,7 @@ public class UsernameTokenTest extends o
             // Verification should fail as the password is bad
             //
             verify(utDoc);
-            throw new Exception("Expected failure due to a bad password");
+            fail("Expected failure due to a bad password");
         } catch (WSSecurityException ex) {
             assertTrue(ex.getErrorCode() == WSSecurityException.FAILED_AUTHENTICATION);
             // expected
@@ -592,7 +565,7 @@ public class UsernameTokenTest extends o
             // Verification should fail as the password is bad
             //
             verify(utDoc);
-            throw new Exception("Expected failure due to a bad password");
+            fail("Expected failure due to a bad password");
         } catch (WSSecurityException ex) {
             assertTrue(ex.getErrorCode() == WSSecurityException.FAILED_AUTHENTICATION);
             // expected
@@ -678,10 +651,8 @@ public class UsernameTokenTest extends o
      * @param env soap envelope
      * @throws java.lang.Exception Thrown when there is a problem in verification
      */
-    private void verify(Document doc) throws Exception {
-        LOG.info("Before verifying UsernameToken....");
-        secEngine.processSecurityHeader(doc, null, callbackHandler, null);
-        LOG.info("After verifying UsernameToken....");
+    private List<WSSecurityEngineResult> verify(Document doc) throws Exception {
+        return secEngine.processSecurityHeader(doc, null, callbackHandler, null);
     }
     
     /**

Added: webservices/wss4j/trunk/src/test/java/org/apache/ws/security/validate/ValidatorTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/test/java/org/apache/ws/security/validate/ValidatorTest.java?rev=1066893&view=auto
==============================================================================
--- webservices/wss4j/trunk/src/test/java/org/apache/ws/security/validate/ValidatorTest.java (added)
+++ webservices/wss4j/trunk/src/test/java/org/apache/ws/security/validate/ValidatorTest.java Thu Feb  3 17:47:43 2011
@@ -0,0 +1,172 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.ws.security.validate;
+
+import javax.security.auth.callback.CallbackHandler;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityEngineResult;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.common.SOAPUtil;
+import org.apache.ws.security.common.UsernamePasswordCallbackHandler;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.security.message.WSSecHeader;
+import org.apache.ws.security.message.WSSecSignature;
+import org.apache.ws.security.message.WSSecTimestamp;
+import org.apache.ws.security.message.WSSecUsernameToken;
+import org.w3c.dom.Document;
+
+/**
+ * A test-case for Validators, check for non-standard behaviour by plugging in
+ * Validator implementations.
+ */
+public class ValidatorTest extends org.junit.Assert {
+    private static final Log LOG = LogFactory.getLog(ValidatorTest.class);
+    private WSSecurityEngine secEngine = new WSSecurityEngine();
+
+    /**
+     * This is a test for processing an expired Timestamp.
+     */
+    @org.junit.Test
+    public void testExpiredTimestamp() throws Exception {
+
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        
+        WSSecTimestamp timestamp = new WSSecTimestamp();
+        timestamp.setTimeToLive(-1);
+        Document createdDoc = timestamp.build(doc, secHeader);
+
+        if (LOG.isDebugEnabled()) {
+            String outputString = 
+                org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(createdDoc);
+            LOG.debug(outputString);
+        }
+        
+        // The default behaviour is that the Timestamp validation will fail
+        WSSConfig wssConfig = WSSConfig.getNewInstance();
+        try {
+            verify(createdDoc, wssConfig, null, null);
+            fail("Expected failure on an expired timestamp");
+        } catch (WSSecurityException ex) {
+            assertTrue(ex.getErrorCode() == WSSecurityException.MESSAGE_EXPIRED); 
+        }
+
+        // Now switch out the default Timestamp validator
+        wssConfig.setValidator(WSSecurityEngine.TIMESTAMP, NoOpValidator.class);
+        verify(createdDoc, wssConfig, null, null);
+    }
+    
+    /**
+     * Test for processing an untrusted signature
+     */
+    @org.junit.Test
+    public void testUntrustedSignature() throws Exception {
+        WSSecSignature sign = new WSSecSignature();
+        sign.setUserInfo("wss40", "security");
+        sign.setKeyIdentifierType(WSConstants.X509_KEY_IDENTIFIER);
+
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        Crypto crypto = CryptoFactory.getInstance("wss40.properties");
+        Document signedDoc = sign.build(doc, crypto, secHeader);
+        
+        if (LOG.isDebugEnabled()) {
+            String outputString = 
+                org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
+            LOG.debug(outputString);
+        }
+        
+        // The default behaviour is that trust verification will fail
+        Crypto cryptoCA = CryptoFactory.getInstance("crypto.properties");
+        WSSConfig wssConfig = WSSConfig.getNewInstance();
+        try {
+            verify(signedDoc, wssConfig, null, cryptoCA);
+            throw new Exception("Failure expected on issuer serial");
+        } catch (WSSecurityException ex) {
+            assertTrue(ex.getErrorCode() == WSSecurityException.FAILED_AUTHENTICATION);
+            // expected
+        }
+        
+        // Now switch out the default signature validator
+        wssConfig.setValidator(WSSecurityEngine.SIGNATURE, NoOpValidator.class);
+        verify(signedDoc, wssConfig, null, cryptoCA);
+    }
+    
+    /**
+     * Test that adds a UserNameToken with (bad) password text to a WS-Security envelope
+     */
+    @org.junit.Test
+    public void testUsernameTokenBadText() throws Exception {
+        WSSecUsernameToken builder = new WSSecUsernameToken();
+        builder.setPasswordType(WSConstants.PASSWORD_TEXT);
+        builder.setUserInfo("wernerd", "verySecre");
+        
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        Document signedDoc = builder.build(doc, secHeader);
+        
+        if (LOG.isDebugEnabled()) {
+            String outputString = 
+                org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
+            LOG.debug(outputString);
+        }
+        
+        // The default behaviour is that password verification will fail
+        WSSConfig wssConfig = WSSConfig.getNewInstance();
+        try {
+            verify(signedDoc, wssConfig, new UsernamePasswordCallbackHandler(), null);
+            fail("Failure expected on a bad password text");
+        } catch (WSSecurityException ex) {
+            assertTrue(ex.getErrorCode() == WSSecurityException.FAILED_AUTHENTICATION);
+            // expected
+        }
+        
+        // Now switch out the default UsernameToken validator
+        wssConfig.setValidator(WSSecurityEngine.USERNAME_TOKEN, NoOpValidator.class);
+        verify(signedDoc, wssConfig, new UsernamePasswordCallbackHandler(), null);
+    }
+
+
+    /**
+     * Verifies the soap envelope
+     * 
+     * @param env soap envelope
+     * @param wssConfig
+     * @throws java.lang.Exception Thrown when there is a problem in verification
+     */
+    private java.util.List<WSSecurityEngineResult> verify(
+        Document doc, WSSConfig wssConfig, CallbackHandler cb, Crypto crypto
+    ) throws Exception {
+        secEngine.setWssConfig(wssConfig);
+        return secEngine.processSecurityHeader(doc, null, cb, crypto);
+    }
+    
+    
+}



Mime
View raw message