You are viewing a plain text version of this content. The canonical link for it is here.
Posted to wss4j-dev@ws.apache.org by fa...@apache.org on 2008/04/17 21:09:43 UTC

svn commit: r649233 - in /webservices/wss4j/trunk: src/org/apache/ws/security/handler/WSHandler.java test/wssec/TestWSSecurityGetPassword.java

Author: fadushin
Date: Thu Apr 17 12:09:39 2008
New Revision: 649233

URL: http://svn.apache.org/viewvc?rev=649233&view=rev
Log:
WSS-113 mild refactor of WSHandler.getPassword
 * Committed Colm's fix, which preserves the useranme and action
   when the WSPasswordCallback is created from a MessageContext.

Thanks for the fix, and the comprehensive testing, Colm!


Added:
    webservices/wss4j/trunk/test/wssec/TestWSSecurityGetPassword.java   (with props)
Modified:
    webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandler.java

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=649233&r1=649232&r2=649233&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 Thu Apr 17 12:09:39 2008
@@ -662,7 +662,6 @@
                                           RequestData reqData)
             throws WSSecurityException {
         WSPasswordCallback pwCb = null;
-        String password = null;
         CallbackHandler cbHandler = null;
         String err = "provided null or empty password";
         Object mc = reqData.getMsgContext();
@@ -672,18 +671,21 @@
             // Null passwords are not always a problem: if the callback was called to provide a username instead.
         } else if ((cbHandler = (CallbackHandler) getProperty(mc, refProp)) != null) {
             pwCb = performCallback(cbHandler, username, doAction);
-        } else if ((password = getPassword(mc)) == null) {
-        	// TODO: hmm. does this also need changed for username processing?
-            throw new WSSecurityException("WSHandler: application " + err);
         } else {
-        	// TODO: hmm. does this also need changed for username processing?
-            setPassword(mc, null);
-            pwCb = new WSPasswordCallback("", WSPasswordCallback.UNKNOWN);
+            //
+            // If a callback isn't configured then try to get the password
+            // from the message context
+            //
+            String password = getPassword(mc);
+            if (password == null) {
+                throw new WSSecurityException("WSHandler: application " + err);
+            }
+            pwCb = constructPasswordCallback(username, doAction);
             pwCb.setPassword(password);
         }
         return pwCb;
     }
-
+    
     private WSPasswordCallback readPwViaCallbackClass(String callback,
                                                       String username,
                                                       int doAction,
@@ -722,22 +724,7 @@
                                                int doAction)
             throws WSSecurityException {
 
-        WSPasswordCallback pwCb = null;
-        int reason = 0;
-
-        switch (doAction) {
-        case WSConstants.UT:
-        case WSConstants.UT_SIGN:
-                reason = WSPasswordCallback.USERNAME_TOKEN;
-                break;
-            case WSConstants.SIGN:
-                reason = WSPasswordCallback.SIGNATURE;
-                break;
-            case WSConstants.ENCR:
-                reason = WSPasswordCallback.KEY_NAME;
-                break;
-        }
-        pwCb = new WSPasswordCallback(username, reason);
+        WSPasswordCallback pwCb = constructPasswordCallback(username, doAction);
         Callback[] callbacks = new Callback[1];
         callbacks[0] = pwCb;
         /*
@@ -749,6 +736,28 @@
             throw new WSSecurityException("WSHandler: password callback failed", e);
         }
         return pwCb;
+    }
+    
+    private WSPasswordCallback constructPasswordCallback(
+        String username,
+        int doAction
+    ) throws WSSecurityException {
+            
+        int reason = WSPasswordCallback.UNKNOWN;
+            
+        switch (doAction) {
+        case WSConstants.UT:
+        case WSConstants.UT_SIGN:
+            reason = WSPasswordCallback.USERNAME_TOKEN;
+            break;
+        case WSConstants.SIGN:
+            reason = WSPasswordCallback.SIGNATURE;
+            break;
+        case WSConstants.ENCR:
+            reason = WSPasswordCallback.KEY_NAME;
+            break;
+        }
+        return new WSPasswordCallback(username, reason);
     }
 
     private void splitEncParts(String tmpS, Vector parts, RequestData reqData)

Added: webservices/wss4j/trunk/test/wssec/TestWSSecurityGetPassword.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/wssec/TestWSSecurityGetPassword.java?rev=649233&view=auto
==============================================================================
--- webservices/wss4j/trunk/test/wssec/TestWSSecurityGetPassword.java (added)
+++ webservices/wss4j/trunk/test/wssec/TestWSSecurityGetPassword.java Thu Apr 17 12:09:39 2008
@@ -0,0 +1,308 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package wssec;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.axis.Message;
+import org.apache.axis.MessageContext;
+import org.apache.axis.client.AxisClient;
+import org.apache.axis.utils.XMLUtils;
+import org.apache.axis.configuration.NullProvider;
+import org.apache.axis.message.SOAPEnvelope;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.action.Action;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoBase;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.security.handler.WSHandler;
+import org.apache.ws.security.handler.RequestData;
+import org.apache.ws.security.handler.WSHandlerConstants;
+import org.apache.ws.security.message.WSSecSignature;
+import org.apache.ws.security.message.WSSecHeader;
+import org.apache.ws.security.message.WSSecUsernameToken;
+import org.apache.ws.security.processor.Processor;
+import org.w3c.dom.Document;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+
+/**
+ * WS-Security Test Case for the getPassword method in WSHandler.
+ * <p/>
+ */
+public class TestWSSecurityGetPassword extends TestCase {
+    private static Log log = LogFactory.getLog(TestWSSecurityGetPassword.class);
+    static final String NS = "http://www.w3.org/2000/09/xmldsig#";
+    static final String soapMsg = 
+        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" 
+        + "<SOAP-ENV:Envelope "
+        +   "xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" "
+        +   "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
+        +   "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" 
+        +   "<SOAP-ENV:Body>" 
+        +       "<add xmlns=\"http://ws.apache.org/counter/counter_port_type\">" 
+        +           "<value xmlns=\"\">15</value>" 
+        +       "</add>" 
+        +   "</SOAP-ENV:Body>" 
+        + "</SOAP-ENV:Envelope>";
+
+    static final Crypto crypto = CryptoFactory.getInstance();
+
+    MessageContext msgContext;
+    SOAPEnvelope unsignedEnvelope;
+
+    /**
+     * TestWSSecurity constructor
+     * <p/>
+     * 
+     * @param name name of the test
+     */
+    public TestWSSecurityGetPassword(String name) {
+        super(name);
+    }
+
+    /**
+     * JUnit suite
+     * <p/>
+     * 
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestWSSecurityGetPassword.class);
+    }
+
+    /**
+     * Main method
+     * <p/>
+     * 
+     * @param args command line args
+     */
+    public static void main(String[] args) {
+        junit.textui.TestRunner.run(suite());
+    }
+
+    /**
+     * Setup method
+     * <p/>
+     * 
+     * @throws java.lang.Exception Thrown when there is a problem in setup
+     */
+    protected void setUp() throws Exception {
+        AxisClient tmpEngine = new AxisClient(new NullProvider());
+        msgContext = new MessageContext(tmpEngine);
+        unsignedEnvelope = getSOAPEnvelope();
+    }
+
+    /**
+     * Constructs a soap envelope
+     * <p/>
+     * 
+     * @return soap envelope
+     * @throws java.lang.Exception if there is any problem constructing the soap envelope
+     */
+    protected SOAPEnvelope getSOAPEnvelope() throws Exception {
+        InputStream in = new ByteArrayInputStream(soapMsg.getBytes());
+        Message msg = new Message(in);
+        msg.setMessageContext(msgContext);
+        return msg.getSOAPEnvelope();
+    }
+
+    /**
+     * A unit test for {@link WSHandler#getPassword(String, int, String, String, RequestData)},
+     * where the password is obtained from the Message Context.
+     */
+    public void
+    testGetPasswordRequestContextUnit() throws Exception {
+        
+        final WSSConfig cfg = WSSConfig.getNewInstance();
+        final RequestData reqData = new RequestData();
+        reqData.setWssConfig(cfg);
+        java.util.Map messageContext = new java.util.TreeMap();
+        messageContext.put("password", "securityPassword");
+        reqData.setMsgContext(messageContext);
+        
+        WSHandler handler = new MyHandler();
+        WSPasswordCallback callback = 
+            handler.getPassword(
+                "bob", 
+                WSConstants.UT, 
+                "SomeCallbackTag", 
+                "SomeCallbackRef",
+                reqData
+            );
+        assertTrue("bob".equals(callback.getIdentifer()));
+        assertTrue("securityPassword".equals(callback.getPassword()));
+        assertTrue(WSPasswordCallback.USERNAME_TOKEN == callback.getUsage());
+    }
+    
+    /**
+     * A WSHandler test for {@link WSHandler#getPassword(String, int, String, String, RequestData)},
+     * where the password is obtained from the Message Context.
+     */
+    public void
+    testGetPasswordRequestContext() throws Exception {
+        
+        final WSSConfig cfg = WSSConfig.getNewInstance();
+        final RequestData reqData = new RequestData();
+        reqData.setWssConfig(cfg);
+        reqData.setUsername("bob");
+        reqData.setPwType(WSConstants.PASSWORD_TEXT);
+        java.util.Map messageContext = new java.util.TreeMap();
+        messageContext.put("password", "securityPassword");
+        reqData.setMsgContext(messageContext);
+        
+        final java.util.Vector actions = new java.util.Vector();
+        actions.add(new Integer(WSConstants.UT));
+        Document doc = unsignedEnvelope.getAsDocument();
+        MyHandler handler = new MyHandler();
+        handler.doit(
+            WSConstants.UT, 
+            doc, 
+            reqData, 
+            actions
+        );
+        
+        String outputString = 
+            org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
+        if (log.isDebugEnabled()) {
+            log.debug(outputString);
+        }
+        assertTrue(outputString.indexOf("bob") != -1);
+        assertTrue(outputString.indexOf("securityPassword") != -1);
+    }
+    
+    /**
+     * A test for {@link WSHandler#getPassword(String, int, String, String, RequestData)},
+     * where the password is obtained from a Callback Handler, which is placed on the 
+     * Message Context using a reference.
+     */
+    public void
+    testGetPasswordCallbackHandlerRef() throws Exception {
+        
+        final WSSConfig cfg = WSSConfig.getNewInstance();
+        final RequestData reqData = new RequestData();
+        reqData.setWssConfig(cfg);
+        reqData.setUsername("bob");
+        reqData.setPwType(WSConstants.PASSWORD_TEXT);
+        java.util.Map messageContext = new java.util.TreeMap();
+        messageContext.put(
+            WSHandlerConstants.PW_CALLBACK_REF, 
+            new MyCallbackHandler()
+        );
+        reqData.setMsgContext(messageContext);
+        
+        final java.util.Vector actions = new java.util.Vector();
+        actions.add(new Integer(WSConstants.UT));
+        Document doc = unsignedEnvelope.getAsDocument();
+        MyHandler handler = new MyHandler();
+        handler.doit(
+            WSConstants.UT, 
+            doc, 
+            reqData, 
+            actions
+        );
+        
+        String outputString = 
+            org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
+        if (log.isDebugEnabled()) {
+            log.debug(outputString);
+        }
+        assertTrue(outputString.indexOf("bob") != -1);
+        assertTrue(outputString.indexOf("securityPassword") != -1);
+    }
+    
+
+    /**
+     * a trivial extension of the WSHandler type
+     */
+    public static class MyHandler extends WSHandler {
+        
+        public Object 
+        getOption(String key) {
+            return null;
+        }
+        
+        public void 
+        setProperty(
+            Object msgContext, 
+            String key, 
+            Object value
+        ) {
+        }
+
+        public Object 
+        getProperty(Object ctx, String key) {
+           return ((java.util.Map)ctx).get(key);
+        }
+    
+        public void 
+        setPassword(Object msgContext, String password) {
+        }
+        
+        public String 
+        getPassword(Object msgContext) {
+            return (String)((java.util.Map)msgContext).get("password");
+        }
+        
+        void doit(
+            int action, 
+            Document doc,
+            RequestData reqData, 
+            java.util.Vector actions
+        ) throws org.apache.ws.security.WSSecurityException {
+            doSenderAction(
+                action, 
+                doc, 
+                reqData, 
+                actions,
+                true
+            );
+        }
+    }
+    
+    public static class MyCallbackHandler implements CallbackHandler {
+        public void handle(Callback[] callbacks)
+            throws IOException, UnsupportedCallbackException {
+            for (int i = 0; i < callbacks.length; i++) {
+                if (callbacks[i] instanceof WSPasswordCallback) {
+                    WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
+                    if (pc.getIdentifer() == "bob") {
+                        pc.setPassword("securityPassword");
+                    }
+                } else {
+                    throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
+                }
+            }
+        }
+    }
+    
+}

Propchange: webservices/wss4j/trunk/test/wssec/TestWSSecurityGetPassword.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: webservices/wss4j/trunk/test/wssec/TestWSSecurityGetPassword.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date



---------------------------------------------------------------------
To unsubscribe, e-mail: wss4j-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: wss4j-dev-help@ws.apache.org