Wednesday, November 4, 2009

How to configure External Database for WSO2 Business Process Server

WSO2BPS (which allows you to easily deploy and manage complex BPEL services) can be configured to use external database other than the embedded Derby database as it's persistence storage.

Lets configure External database for BPS

1. Set up and start your database server

WSO2BPS (version - 1.1.1) supports for Mysql ,Oracle and MSSQL Database server.  Latest Vesion of WSO2BPS would support for PostgreSQL.


2. Create a database

3. Extract wso2wbps-1.1.1.zip and Load the BPS schema into that database using provided SQL scripts.

(For example if you are using mysql as your database server, use mysql.sql script located inside 'WSO2BPS/dbscripts/bps' directory to create the BPS schema)

use command "mysql -u root -p bps < /home/asela/BPS/wso2bps-1.1.0-SNAPSHO/dbscripts/bps/mysql.sql"
 
4. Create file named 'datasources.properties' inside WSO2BPS/conf directory

5. Add following configuration in datasources.properties file 


Following is sample configuration for Mysql.


synapse.datasources=bpsds
synapse.datasources.icFactory=com.sun.jndi.rmi.registry.RegistryContextFactory
synapse.datasources.providerPort=2199

synapse.datasources.bpsds.registry=JNDI
synapse.datasources.bpsds.type=BasicDataSource
synapse.datasources.bpsds.driverClassName=com.mysql.jdbc.Driver
synapse.datasources.bpsds.url=jdbc:mysql://localhost:3306/bps
synapse.datasources.bpsds.username=root
synapse.datasources.bpsds.password=asela
synapse.datasources.bpsds.dsName=bpsds
synapse.datasources.bpsds.maxActive=100
synapse.datasources.bpsds.maxIdle=20
synapse.datasources.bpsds.maxWait=10000


in first three lines, data source names, initial context factory and provider port have been configured. Here "bpsds"is used as data source name.

other lines are specified the properties for previously created database. Make sure that your database url, username and password are correctly specified.

6.Open bps.xml file inside WSO2BPS/conf directory and add following parameters


7.Copy the JDBC driver jar file into the 'WSO2BPS/repository/components/lib' directory


8.Then start the WSO2BPS server 


if correctly configured You will see following log in WSO2BPS startup..

[2010-05-01 17:49:56,056]  INFO -  DataSources will be registered in the JNDI context with provider PROP_URL : rmi://asela-laptop:2199
.....................................


[2010-05-01 17:49:59,490]  INFO -  ODE using external DataSource "bpsds".
[2010-05-01 17:49:59,491]  INFO -  Using DAO Connection Factory class: org.apache.ode.dao.jpa.BPELDAOConnectionFactoryImpl
[2010-05-01 17:49:59,491]  INFO -  Using DAO Connection Factory class org.apache.ode.dao.jpa.BPELDAOConnectionFactoryImpl.
[2010-05-01 17:50:00,701]  INFO -  Registering E4X Extension...
[2010-05-01 17:50:00,761]  INFO -  BPEL Server Started.
[2010-05-01 17:50:00,806]  INFO -  Starting OpenJPA 1.1.0
[2010-05-01 17:50:00,914]  INFO -  Using dictionary class "org.apache.openjpa.jdbc.sql.MySQLDictionary".
 


Tuesday, November 3, 2009

Sample BPEL to ensure the security in External partner service

Resources you need

1.WSO2BPS (which allows you to easily deploy and manage bpel services)
2.WSO2WSAS
3.SecurePartnerBPEL.zip
4.SecurePartnerService.aar
5.sample_keys.zip
6.PWCBHandler.zip

First deploy External partner service in WSO2WSAS and secure it.


1. Extract wso2wsas-3.1.1.zip and run WSAS server.

wso2wsas-3.1.1/bin/wso2server.sh - in unix
wso2wsas-3.1.1/bin/wso2server.bat - in windows

Please refer README file and More details about WSO2WSAS is available at here

2. Upload SecurePartnerService.aar Axis2 service





3. Add new keystore to WSAS


Extract sample_keys.zip and browse to the service.jks

provide following passwords, Key store Password= apache Private Key Password=apache





4. Add new role and user



Add new role called bpsusers

Then add new user

provide username = client, password=apache (these username and password must be in PWCBHandler.jar)

select bpsusers role for client user


5.Go to Service Dashboard of SecurePartnerService and enable security



6. Select any security Scenarios (select service.jks as Trusted Key Stores, Private key store and bpsusers as User Groups)




Then deploy BPEL service in WSO2BPS




1. Extract wso2wbps-1.1.0.zip and copy PWCBHandler.jar to WSO2BPS/repository/components/lib and Extract sample_keys.zip in to WSO2BPS/samples. Then run BPS server.

wso2wsas-3.1.1/bin/wso2server.sh - in unix
wso2wsas-3.1.1/bin/wso2server.bat - in windows

Please refer README file and More details about WSO2BPS is available at here

2.Deploy bpel service in BPS (just click Add BPEL and browse the SecurePartnerBPEL.zip)



3.Under Deployed Services, you can see SecurePartnerBPELServiceService service.


4.Open tcpmon( WSO2BPS/bin/tcpmon.sh) and configure it to monitor the SOAP messages

Listen port=9765 Target port= port of your SecurePartnerService


5.Now try this service using Try it

Enter the security scenario number that is used to secure your External partner service.


Service returns the detail about security scenario that your External partner service is used.




Note = tcpmon can not use for UsernameToken security scenario. According to SecurePartnerBPEL.zip, you must start your External partner service in port=9444. To change http and https port, configure "port" parameter(9763) in your axis2.xml and transport.xml

Sunday, October 18, 2009

Secured BPEL services


Security is one of the essential  requirement for BPEL services as today BPEL services are mostly used for banking, paying and crediting applications. So BPEL services must be able to secure very reliable and flexible manner. WSO2BPS is the Best solution for it. Also it provides to configure security for your BPEL service in a user friendly manner.

First Lets deploy a simple BPEL in WSO2BPS.


1. Download latest release of WSO2BPS from Here

2. Extract wso2bps-1.1.X.zip  Lets define extracted location as BPS_HOME


3. Start BPS server  Run the wso2server.sh (in unix) or wso2server.bat (in windows) file in the BPS_HOME/bin directory
Once the server starts, point your Web browser to https://localhost:9443/carbon/

4. Deploy BPEL package just click on Add BPEL button and browse the Location of Your BPEL Package.  You can download sample BPEL Package (HelloWorld.zip) from here. Lets used it for further discussions.


In service list you will see our BPEL services (HelloService) and you can invoke this service. (by clicking on "Try this service" in WSO2BPS or Using Soapui).


So above BPEL service has not secured. Any one could be able to invoke it.




Now it is time to secure the our BPEL service


5.Go to Service Dashboard of BPEL service and enable security

You can see there are several QoS configurations for our BPEL service. Lets select the security








6. Select any security Scenarios 


As you can see, 15 security configuration scenarios are pre-defined for our BPEL service. You can use any one out of this Because I am going to write a client that works for all...



Here i am used default key store (wso2carbon.jks) as the Trusted Key Stores and Private key Store.  Or you can simply upload a New key store using BPS UI.



Now lets invoke secured service from security client

7. Create a Java project with SecurityClient.java and client.properties 
 files

8. Add Following configuration parameters to client.properties file

clientRepo = Path for Client repository location. Sample repo can be found in BPS_HOME/samples/axis2Server/repository location. or can download from here (must contains addressing.mar and rampart.mar in module directory)
clientKey =Path for Client's Key Store.  Here I am using same key Store (wso2carbon.jks) which is used to secure BPEL service. you can find it from BPS_HOME/resources/security. You can use any key Store but remember to import BPS cert to client key store and client cert to BPS key store. Because to fulfill the requirement for signing and encryption
securityPolicyLocation=Path for the client side security policy files. You can download 15 policy files from here.
trustStore= This is trusted store that is used for ssl communication on https. It should contains the BPS cert.you can use same key store for this. (wso2carbon.jks)
securityScenarioNo=Security scenario number that used to secure the BPEL service.
SoapAction =You can find it from wsdl
endpointHttp =Http endpont of BPEL service
endpointHttpS=Https endpont of BPEL service
body = Body part of your Soap message


Sample configurations



clientRepo=/home/asela/Wso2/BPS/BPS_Client/Client_Repo
clientKey =/home/asela/Wso2/BPS/BPS_Client/sample_keys/client.jks
clientKey =/home/asela/Wso2/BPS/BPS_Client/sample_keys/wso2carbon.jks
securityPolicyLocation=/home/asela/Wso2/BPS/BPS_Client/security_scenarios
trustStore=/home/asela/Wso2/BPS/BPS_Client/sample_keys/wso2carbon.jks
securityScenarioNo=7
SoapAction =urn:hello
endpointHttp =http://localhost:9763/services/HelloService/
endpointHttpS =https://10.100.1.152:9443/services/HelloService/
body =<p:hello xmlns:p=\"http://ode/bpel/unit-test.wsdl\"> <TestPart>Wso2</TestPart> </p:hello>


9. Copy Following Java code 

it is simple... Nothing to change...



import org.apache.neethi.Policy;
import org.apache.neethi.PolicyEngine;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axiom.om.impl.llom.util.AXIOMUtil;
import org.apache.axiom.om.OMElement;
import org.apache.rampart.policy.model.RampartConfig;
import org.apache.rampart.policy.model.CryptoConfig;
import org.apache.rampart.RampartMessageData;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.client.Options;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.ws.security.WSPasswordCallback;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.callback.CallbackHandler;
import java.io.File;
import java.io.IOException;
import java.io.FileInputStream;
import java.util.Properties;

public class SecurityClient implements CallbackHandler {

 public static void main(String srgs[]) {

        SecurityClient securityCl = new SecurityClient();
        OMElement result = null;
          try {
                result = securityCl.runSecurityClient();
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println(result.toString());

        }

    public OMElement runSecurityClient( ) throws Exception {

        Properties properties = new Properties();
        FileInputStream freader=new FileInputStream("."+File.separator+"src"+File.separator+"client.properties");
        properties.load(freader);
        String clientRepo  = properties.getProperty("clientRepo");
        String endpointHttpS   = properties.getProperty("endpointHttpS");
        String endpointHttp   = properties.getProperty("endpointHttp");
        int securityScenario =Integer.parseInt(properties.getProperty("securityScenarioNo"));
        String clientKey = properties.getProperty("clientKey");
        String SoapAction = properties.getProperty("SoapAction");
        String body = properties.getProperty("body");
        String trustStore=properties.getProperty("trustStore");
        String securityPolicy =properties.getProperty("securityPolicyLocation");

        OMElement result = null;


        System.setProperty("javax.net.ssl.trustStore", trustStore);
        System.setProperty("javax.net.ssl.trustStorePassword", "wso2carbon");

//        System.setProperty("javax.net.ssl.keyStore", keyStore + File.separator +  "wso2carbon.jks");
//        System.setProperty("javax.net.ssl.keyStorePassword", "wso2carbon");

        ConfigurationContext ctx = ConfigurationContextFactory.createConfigurationContextFromFileSystem(clientRepo, null);
        ServiceClient sc = new ServiceClient(ctx, null);
        sc.engageModule("rampart");
        sc.engageModule("addressing");

        Options opts = new Options();

            if(securityScenario==1){
                opts.setTo(new EndpointReference(endpointHttpS));
            }else{
                opts.setTo(new EndpointReference(endpointHttp));
            }

        opts.setAction(SoapAction);

            if(securityScenario!=0){
                try {
                    String securityPolicyPath=securityPolicy+File.separator +"scenario"+securityScenario+"-policy.xml";
                    opts.setProperty(RampartMessageData.KEY_RAMPART_POLICY, loadPolicy(securityPolicyPath,clientKey));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        sc.setOptions(opts);
        result = sc.sendReceive(AXIOMUtil.stringToOM(body));
        System.out.println(result.getFirstElement().getText());
        return result;
    }
   
    public Policy loadPolicy(String xmlPath , String clientKey) throws Exception {

        StAXOMBuilder builder = new StAXOMBuilder(xmlPath);
        Policy policy = PolicyEngine.getPolicy(builder.getDocumentElement());

        RampartConfig rc = new RampartConfig();

        rc.setUser("admin");
        rc.setUserCertAlias("wso2carbon");
        rc.setEncryptionUser("wso2carbon");
        rc.setPwCbClass(SecurityClient.class.getName());

        CryptoConfig sigCryptoConfig = new CryptoConfig();
        sigCryptoConfig.setProvider("org.apache.ws.security.components.crypto.Merlin");

        Properties prop1 = new Properties();
        prop1.put("org.apache.ws.security.crypto.merlin.keystore.type", "JKS");
        prop1.put("org.apache.ws.security.crypto.merlin.file", clientKey);
        prop1.put("org.apache.ws.security.crypto.merlin.keystore.password", "wso2carbon");
        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", clientKey);
        prop2.put("org.apache.ws.security.crypto.merlin.keystore.password", "wso2carbon");
        encrCryptoConfig.setProp(prop2);

        rc.setSigCryptoConfig(sigCryptoConfig);
        rc.setEncrCryptoConfig(encrCryptoConfig);

        policy.addAssertion(rc);
        return policy;
    }



    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {

        WSPasswordCallback pwcb = (WSPasswordCallback) callbacks[0];
        String id = pwcb.getIdentifer();
        int usage = pwcb.getUsage();

        if (usage == WSPasswordCallback.USERNAME_TOKEN) {

           if ("admin".equals(id)) {
               pwcb.setPassword("admin");
           }

        } else if (usage == WSPasswordCallback.SIGNATURE || usage == WSPasswordCallback.DECRYPT) {

            if ("wso2carbon".equals(id)) {
                pwcb.setPassword("wso2carbon");
            }
        }
    }
}

10. Add relevant libraries to your class path 

How do we find those libraries.. there are many. It is easy Go to BPS_HOME/bin and run ant command. You will see created jar file in BPS_HOME/repository/lib  directory. Do not forget to add xalan jar that is in BPS_HOME/lib/endorsed directory.

11.Then run your secured client
Now you are able to secure your BPEL service using all 15 security scenarios..........!!!

Note1 :- if You want to invoke a secured BPEL service(not HelloWorld).You can  get the body part of soap message using soapui and SoapAction using WSDL
    1. Create a project in soapui using your service's WSDL
    2. Copy the body part from your soap request message.( make sure to copy the correct namespace)
    3. Find value of Action attribute from your service's WSDL


Note2 :- if you want to trace the secured soap messages , Open tcpmon( WSO2BPS/bin/tcpmon.sh) and configure it  and change http end point of your client.properties file
     Listen port   = Port that you configure in client.properties file
     Target port  = Actual port of your BPEL service