Author: keith
Date: Thu Jul 10 02:51:59 2008
New Revision: 19084
URL: http://wso2.org/svn/browse/wso2?view=rev&revision=19084

Log:
Adding support for using keystores when calling secured services. With this un 
place we can talk to services that engage security scenario2


Added:
   
trunk/mashup/java/modules/hostobjects/src/org/wso2/mashup/hostobjects/wsrequest/PasswordCallbackHandler.java
Modified:
   trunk/mashup/java/modules/core/src/org/wso2/mashup/MashupConstants.java
   
trunk/mashup/java/modules/hostobjects/src/org/wso2/mashup/hostobjects/wsrequest/WSRequestHostImpl.java

Modified: 
trunk/mashup/java/modules/core/src/org/wso2/mashup/MashupConstants.java
URL: 
http://wso2.org/svn/browse/wso2/trunk/mashup/java/modules/core/src/org/wso2/mashup/MashupConstants.java?rev=19084&r1=19083&r2=19084&view=diff
==============================================================================
--- trunk/mashup/java/modules/core/src/org/wso2/mashup/MashupConstants.java     
(original)
+++ trunk/mashup/java/modules/core/src/org/wso2/mashup/MashupConstants.java     
Thu Jul 10 02:51:59 2008
@@ -62,6 +62,7 @@
     public static final String SECURITY_CONFIG_KEYSTORE_PASSWORD = "Password";
     public static final String SECURITY_CONFIG_KEYSTORE_KEYALIAS = "KeyAlias";
     public static final String SECURITY_CONFIG_KEYSTORE_KEYPASSWORD = 
"KeyPassword";
+    public static final String SECURITY_CONFIG_KEYSTORE_KEYSTOREDIR = 
"KeyStoresDir";
 
     public static final String EMAIL_RELAY_HOST = "email_relay_host";
     public static final String WEBAPP_URL = "webapp_url";

Added: 
trunk/mashup/java/modules/hostobjects/src/org/wso2/mashup/hostobjects/wsrequest/PasswordCallbackHandler.java
URL: 
http://wso2.org/svn/browse/wso2/trunk/mashup/java/modules/hostobjects/src/org/wso2/mashup/hostobjects/wsrequest/PasswordCallbackHandler.java?pathrev=19084
==============================================================================
--- (empty file)
+++ 
trunk/mashup/java/modules/hostobjects/src/org/wso2/mashup/hostobjects/wsrequest/PasswordCallbackHandler.java
        Thu Jul 10 02:51:59 2008
@@ -0,0 +1,128 @@
+package org.wso2.mashup.hostobjects.wsrequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSPasswordCallback;
+import org.wso2.mashup.MashupConstants;
+import org.wso2.utils.ServerConfiguration;
+import org.wso2.utils.security.CryptoException;
+import org.wso2.utils.security.CryptoUtil;
+import org.wso2.wsas.persistence.PersistenceManager;
+import org.wso2.wsas.persistence.dataobject.KeyStoreDO;
+import org.wso2.wsas.persistence.dataobject.ServiceUserDO;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import java.io.File;
+import java.io.IOException;
+
+public class PasswordCallbackHandler implements CallbackHandler {
+
+    private static final Log log = 
LogFactory.getLog(PasswordCallbackHandler.class);
+    private String mashupUserName;
+
+    public PasswordCallbackHandler(String mashupUserName) {
+        this.mashupUserName = mashupUserName;
+    }
+
+    public void handle(Callback[] callbacks) throws IOException,
+            UnsupportedCallbackException {
+        for (int i = 0; i < callbacks.length; i++) {
+            if (callbacks[i] instanceof WSPasswordCallback) {
+                WSPasswordCallback passwordCallback = (WSPasswordCallback) 
callbacks[i];
+
+                String username = passwordCallback.getIdentifer();
+                String storedPasswd = getPassword(username);
+
+                switch (passwordCallback.getUsage()) {
+
+                    case WSPasswordCallback.SIGNATURE:
+                    case WSPasswordCallback.DECRYPT:
+                        
passwordCallback.setPassword(this.getPrivateKeyPassword());
+                        break;
+
+                    case WSPasswordCallback.USERNAME_TOKEN_UNKNOWN:
+
+                        String receivedPasswd = passwordCallback.getPassword();
+                        boolean authneticated = receivedPasswd != null &&
+                                receivedPasswd.equals(storedPasswd);
+                        if (!authneticated) {
+                            throw new 
UnsupportedCallbackException(callbacks[i],
+                                                                   "check 
failed");
+                        }
+
+                        break;
+                    default:
+
+                        /*
+                         * When the password is null WS4J reports an error 
saying
+                         * no password available for the user. But its better 
if we
+                         * simply report authentication failure
+                         * Therefore setting the password to be the empty 
string in this
+                         * situation.
+                         */
+                        if (storedPasswd == null) {
+                            storedPasswd = "";
+                        }
+                        passwordCallback.setPassword(storedPasswd);
+                        break;
+
+                }
+
+
+            } else {
+                throw new UnsupportedCallbackException(callbacks[i],
+                                                       "Unrecognized 
Callback");
+            }
+        }
+    }
+
+
+    private String getPrivateKeyPassword() throws IOException {
+        PersistenceManager pm = new PersistenceManager();
+        KeyStoreDO ksDO = pm.getKeyStore(mashupUserName + 
MashupConstants.KEY_STORE_SUFFIX);
+        try {
+            ServerConfiguration config = ServerConfiguration.getInstance();
+            CryptoUtil cryptoUtil =
+                    new CryptoUtil(new File(config.getFirstProperty(
+                            "Security.KeyStore.Location")).getAbsolutePath(),
+                                   
config.getFirstProperty("Security.KeyStore.Password"),
+                                   
config.getFirstProperty("Security.KeyStore.KeyAlias"),
+                                   
config.getFirstProperty("Security.KeyStore.KeyPassword"),
+                                   
config.getFirstProperty("Security.KeyStore.Type"));
+            return new 
String(cryptoUtil.base64DecodeAndDecrypt(ksDO.getPrivateKeyPassword()));
+        } catch (CryptoException e) {
+            throw new IOException(e.getMessage());
+        }
+    }
+
+    /**
+     * @param username The username of the user
+     * @return The password corresponding to the username
+     */
+    private String getPassword(String username) {
+        PersistenceManager pm = new PersistenceManager();
+
+        ServiceUserDO serviceUser = pm.getUser(username);
+        if (serviceUser == null) { // user does not exist?
+            return null;
+        }
+
+        String password = null;
+        try {
+            ServerConfiguration config = ServerConfiguration.getInstance();
+            CryptoUtil cryptoUtil =
+                    new CryptoUtil(new File(config.getFirstProperty(
+                            "Security.KeyStore.Location")).getAbsolutePath(),
+                                   
config.getFirstProperty("Security.KeyStore.Password"),
+                                   
config.getFirstProperty("Security.KeyStore.KeyAlias"),
+                                   
config.getFirstProperty("Security.KeyStore.KeyPassword"),
+                                   
config.getFirstProperty("Security.KeyStore.Type"));
+            password = new 
String(cryptoUtil.base64DecodeAndDecrypt(serviceUser.getPassword()));
+        } catch (CryptoException e) {
+            log.error("Exception occurred while decrypting password", e);
+        }
+        return password;
+    }
+}

Modified: 
trunk/mashup/java/modules/hostobjects/src/org/wso2/mashup/hostobjects/wsrequest/WSRequestHostImpl.java
URL: 
http://wso2.org/svn/browse/wso2/trunk/mashup/java/modules/hostobjects/src/org/wso2/mashup/hostobjects/wsrequest/WSRequestHostImpl.java?rev=19084&r1=19083&r2=19084&view=diff
==============================================================================
--- 
trunk/mashup/java/modules/hostobjects/src/org/wso2/mashup/hostobjects/wsrequest/WSRequestHostImpl.java
      (original)
+++ 
trunk/mashup/java/modules/hostobjects/src/org/wso2/mashup/hostobjects/wsrequest/WSRequestHostImpl.java
      Thu Jul 10 02:51:59 2008
@@ -29,11 +29,10 @@
 import org.apache.axis2.client.async.AxisCallback;
 import org.apache.axis2.context.ConfigurationContext;
 import org.apache.axis2.context.ConfigurationContextFactory;
-import org.apache.axis2.description.AxisOperation;
+import org.apache.axis2.context.MessageContext;
 import org.apache.axis2.description.WSDL2Constants;
 import org.apache.axis2.description.AxisService;
 import org.apache.axis2.description.AxisEndpoint;
-import org.apache.axis2.description.AxisDescription;
 import org.apache.axis2.description.AxisBindingMessage;
 import org.apache.axis2.transport.http.HTTPConstants;
 import org.apache.axis2.transport.http.HttpTransportProperties;
@@ -49,10 +48,10 @@
 import org.apache.rampart.RampartMessageData;
 import org.apache.rampart.policy.RampartPolicyBuilder;
 import org.apache.rampart.policy.RampartPolicyData;
+import org.apache.rampart.policy.model.RampartConfig;
+import org.apache.rampart.policy.model.CryptoConfig;
 import org.apache.ws.secpolicy.WSSPolicyException;
-import org.apache.ws.secpolicy.model.SupportingToken;
-import org.apache.ws.secpolicy.model.Token;
-import org.apache.ws.secpolicy.model.UsernameToken;
+import org.apache.ws.security.handler.WSHandlerConstants;
 import org.mozilla.javascript.Context;
 import org.mozilla.javascript.Function;
 import org.mozilla.javascript.NativeArray;
@@ -67,6 +66,7 @@
 import org.wso2.mashup.utils.MashupUtils;
 import org.wso2.wsas.ServerManager;
 import org.wso2.wsas.ServerConstants;
+import org.wso2.utils.ServerConfiguration;
 
 import javax.wsdl.Definition;
 import javax.wsdl.Port;
@@ -91,6 +91,10 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
+import java.util.Enumeration;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
 
 /**
  * <p/>
@@ -684,29 +688,26 @@
                         //Process policy and build policy data
                         RampartPolicyData policyData = 
RampartPolicyBuilder.build(it);
                         if (policyData != null) {
-                            SupportingToken supportingTokens =
-                                    policyData.getSignedSupportingTokens();
-                            if (policyData.isTransportBinding()) {
-                                if (supportingTokens != null &&
-                                        supportingTokens.getTokens() != null &&
-                                        supportingTokens.getTokens().size() > 
0) {
-                                    ArrayList tokens = 
supportingTokens.getTokens();
-                                    for (Iterator iter = tokens.iterator(); 
iter.hasNext();) {
-
-                                        Token token = (Token) iter.next();
-                                        if (token instanceof UsernameToken) {
-                                            needRampart = true;
-                                        } else {
-                                            throw new MashupFault(
-                                                    
"unsupportedSignedSupportingToken " +
-                                                            "{" + 
token.getName()
-                                                            .getNamespaceURI()
-                                                            + "}" + 
token.getName()
-                                                            .getLocalPart());
-                                        }
-                                    }
-                                }
-                            }
+                            if (policyData.isAsymmetricBinding() ||
+                                    policyData.isSymmetricBinding() ||
+                                    policyData.isTransportBinding()) {
+                                needRampart = true;
+                                Policy attchPolicy = new Policy();
+
+                                MessageContext currentMessageContext =
+                                        
MessageContext.getCurrentMessageContext();
+                                // In order to get the users keystore details 
we need his username. We stick the
+                                // username as a parameter into the service at 
deployment time
+                                String authorName = (String) 
currentMessageContext.getAxisService()
+                                        
.getParameterValue(MashupConstants.MASHUP_AUTHOR_NAME);
+
+
+                                
axisService.addParameter(WSHandlerConstants.PW_CALLBACK_REF,
+                                                         new 
PasswordCallbackHandler(authorName));
+                                attchPolicy.addAssertion(
+                                        wsRequest.getRampartConfig(wsRequest, 
authorName));
+                                
axisService.getPolicySubject().attachPolicy(attchPolicy);
+                            }                            
                         }
                     }
                     if (needRampart) {
@@ -1051,4 +1052,68 @@
             options.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER, 
protocol);
         }
     }
+
+    private RampartConfig getRampartConfig(WSRequestHostImpl wsRequest, String 
authorName) throws MashupFault {
+        System.out.println(
+                "In this demonstration, client will use client.jks and server 
should use\n" +
+                "service.jks.");
+        RampartConfig rc = new RampartConfig();
+
+        CryptoConfig sigCryptoConfig = new CryptoConfig();
+
+        
sigCryptoConfig.setProvider("org.apache.ws.security.components.crypto.Merlin");
+
+        ServerConfiguration serverConfig = ServerConfiguration.getInstance();
+
+        String keyStorePass =
+                serverConfig.getFirstProperty(MashupConstants.SECURITY_CONFIG 
+ "." +
+                        MashupConstants.SECURITY_CONFIG_KEYSTORE + "." + 
MashupConstants
+                        .SECURITY_CONFIG_KEYSTORE_PASSWORD);
+
+        String KeyStoresDir =
+                serverConfig.getFirstProperty(MashupConstants.SECURITY_CONFIG 
+ "." +
+                        MashupConstants.SECURITY_CONFIG_KEYSTORE_KEYSTOREDIR);
+
+        KeyStore keyStore = MashupUtils.getUserKeyStore(authorName);
+        Enumeration enumeration;
+        String user = null;
+        try {
+            enumeration = keyStore.aliases();
+        while (enumeration.hasMoreElements()) {
+            String alias = (String) enumeration.nextElement();
+                if (keyStore.isKeyEntry(alias)) {
+                    user = alias;
+                    break;
+                }
+            }} catch (KeyStoreException e) {
+                throw new MashupFault(e);
+            }
+        rc.setUser(user);
+
+        String keystore = KeyStoresDir + File.separator + authorName +
+                MashupConstants.KEY_STORE_SUFFIX;
+
+        Properties prop1 = new Properties();
+        prop1.put("org.apache.ws.security.crypto.merlin.keystore.type", "JKS");
+        prop1.put("org.apache.ws.security.crypto.merlin.file", keystore);
+        prop1.put("org.apache.ws.security.crypto.merlin.keystore.password", 
keyStorePass);
+        sigCryptoConfig.setProp(prop1);
+
+        CryptoConfig encrCryptoConfig = new CryptoConfig();
+        
encrCryptoConfig.setProvider("org.apache.ws.security.components.crypto.Merlin");
+
+        Properties prop2 = new Properties();
+
+        prop2.put("org.apache.ws.security.crypto.merlin.keystore.type", "JKS");
+
+
+        prop2.put("org.apache.ws.security.crypto.merlin.file", keystore);
+        prop2.put("org.apache.ws.security.crypto.merlin.keystore.password", 
keyStorePass);
+        encrCryptoConfig.setProp(prop2);
+
+        rc.setSigCryptoConfig(sigCryptoConfig);
+        rc.setEncrCryptoConfig(encrCryptoConfig);
+
+        return rc;
+    }
 }
\ No newline at end of file

_______________________________________________
Mashup-dev mailing list
[email protected]
http://wso2.org/cgi-bin/mailman/listinfo/mashup-dev

Reply via email to