Friday, September 23, 2011

cURL tests harness and TLS



In a previous post, I have explained how to use cURL to test harness REST based Web services. One thing I did not described was how to add Transport Layer Security (TLS) in your tests. In other words, how to successfully test REST Web services over HTTPS?

The cURL manual describes a certain number of options that can be used. One of the most convenient option is -k or --insecure. It allows curl to  perform  "insecure" SSL connections and transfers. All SSL connections are attempted to be made secure by using the CA certificate  bundle  installed by  default. So if you SSL connection does not require client side authentication it is a very quick way to test your web service over SSL:

  curl -k https://www.acme.com/api/version


Another useful option can be used if in conjunction to SSL, you need to compress your payload via GZIP for example to optimize the transfer of large messages. In this case, you will use the option -H or --header that will help you specify custom headers to your request:

  curl -H "Accept-Encoding: gzip,deflate" -k https://www.acme.com/api/users/list


Notice in that case that the -k or --insecure option is always placed just in front of URL.

Of course, other headers such as the one described previously can be combined:

  curl -c ./cookies.txt --data-binary @login_password.json -H "Content-Type: application/json" -H "Accept-Encoding: gzip,deflate" -k https://www.acme.com/api/users/token







Wednesday, August 31, 2011

Medication Adherence - How technology can help?



Looking for ideas to reduce the rise of health care cost? Easy! Ask patients to swallow their medication!






According to recent studies, the lack of prescription medication adherence cost between $250 and $300 billion annually, including $100 billion in hospitalization. For example, it is estimated that in the US 89,000 deaths annually are due to non adherence to anti-hypertensive treatments. This problem is particularly acute for patients with coexisting conditions who take a variety of medications sometimes prescribed by different physicians.

Obviously doctors and pharmacists have a critical role to encourage patients and caregivers to administrate medication correctly and rigorously.

Cost is not necessarily the main factor: even when drugs are free, adherence rate is 60% in the US and only %50 in developed countries. In other words, improvements in co-payments structures will only partially improve adherence. Another area of possible improvement will be the use of fee-for-service model.






Another way to improve medication adherence is the proper use of specific technologies:

Here are some suggestions:
  • the integration of practice EMRs systems and pharmacies via HIE solutions (a lot of practices are still using paper).
    • online incentive programs (e.g. provided by the employers) to promote prevention, quality of life and best practices in therapy. It is recognized that financial incentives and other rewards when well designed and targeted can improve adherence (smaller and higher reward frequency is usually more efficient than big and sporadic rewards).
    • advances in personalized medicine can help taylored medication intake and increase medication adherence
    With the amount of money at stake, I am sure there is a large number of companies, including start-ups, who are working hard on this problem. So stay tune!

    Finally, we have to keep in mind, that other factors including lifestyle, psychological issues and health literacy play an important role as well. And these are not negligible!






    Friday, July 29, 2011

    How to test secure web services with soapUI - part #2


    In  a previous article I described how to specify signature and encryption for outgoing Secured Web Services request.

    1. SAML

    In this second article I will talk about SAML and incoming Secure Web Service responses.

    If you are using SAML 1.X then you just need to add a SAML 1.X assertion in the corresponding window.
    You may have to add a timestamp as follow:











































    In this example, we specify 10,000 milliseconds (10 seconds) for the life time of the Timestamp:











































    SAML 1.X assertions are copied and pasted in the SAML tab:








    Of course, if you combine signature and encryption with SAML 1.X. You can those to the configuration tabs as well.

    For SAML 2.0, the only option you have for this version of soapUI is to add it manually to the WSSE section of your SOAP request:











































    2. Incoming Secure Web Service 
    Responses


    Setting up incoming secure Web services responses encrypted and/or signed is easier than for outgoing request:

    1) Make sure that you have Keystores / Certificates tab set - You probably have done that earlier as described in part #1 of this article.
    You verify the signature with public key contained in the server's sender certificate/store and your private key to decrypt what the other server sends you.

















    2) Create an incoming WSS configuration (e.g. my_config_from_server_A) that will decrypt the incoming SOAP requests coming from server A:











































    You specify that you want to use your keystore to decrypt the message and the server's certificate/store to verify the signature of server A
    (theses should appear in the drop box for each field):



























    3) Last, you want to specify that you are using the incoming configuration for each request:



















    Enjoy!




    Monday, June 27, 2011

    Problem initializing the class javax.crypto.SunJCE_b with soapUI ?





    Last week, I have decided to download and  install the lastest soapUI PRO version 4.0 from Eviware.
    I have been using soapUI for some time to test secure SOAP Web services using SSL/TLS as well as encrypting and signing the SOAP payload.

    However when I tried to use my existing projects I end-up with the following errors in my soapUI log:

    Wed Jun 22 11:43:05 PDT 2011:ERROR:java.lang.NoClassDefFoundError: Could not initialize class javax.crypto.SunJCE_b
       java.lang.NoClassDefFoundError: Could not initialize class javax.crypto.SunJCE_b
        at javax.crypto.KeyGenerator.a(DashoA13*..)
        at javax.crypto.KeyGenerator.(DashoA13*..)
        at javax.crypto.KeyGenerator.getInstance(DashoA13*..)
        at org.apache.ws.security.message.WSSecEncrypt.getKeyGenerator(WSSecEncrypt.java:701)
        at org.apache.ws.security.message.WSSecEncrypt.prepare(WSSecEncrypt.java:228)
        at org.apache.ws.security.message.WSSecEncrypt.build(WSSecEncrypt.java:291)
        at com.eviware.soapui.impl.wsdl.support.wss.entries.AddEncryptionEntry.process(AddEncryptionEntry.java:311)
        at com.eviware.soapui.impl.wsdl.support.wss.OutgoingWss.processOutgoing(OutgoingWss.java:157)
        at com.eviware.soapui.impl.wsdl.submit.filters.WssRequestFilter.filterWsdlRequest(WssRequestFilter.java:58)
        at com.eviware.soapui.impl.wsdl.submit.filters.AbstractRequestFilter.filterAbstractHttpRequest(AbstractRequestFilter.java:37)
        at com.eviware.soapui.impl.wsdl.submit.filters.AbstractRequestFilter.filterRequest(AbstractRequestFilter.java:31)
        at com.eviware.soapui.impl.wsdl.submit.transports.http.HttpClientRequestTransport.sendRequest(HttpClientRequestTransport.java:133)
        at com.eviware.soapui.impl.wsdl.WsdlSubmit.run(WsdlSubmit.java:123)
        at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
        at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
        at java.util.concurrent.FutureTask.run(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)
    
    

    A quick search on the web told me to check if my some of my security setup in my JRE was properly configured.
    For this it was recommended to check the security directory under the lib folder (.\Java\jre6\lib\security):
















    I also checked the content of the content of the jar file ./Java/jre6/lib/jce.jar which should contain the missing class in question:  javax.crypto.SunJCE_b

    However everything looked fine. Even though my JRE was almost up-to-date, I finally managed to fix this issue by upgrading my java JRE to the latest version!










    Tuesday, May 31, 2011

    How to test secure web services with soapUI - part #1




    Recently I have been involved in a SOA project which goal is to orchestrate  IHE integration profiles SOAP web services (XCPD & XCA) using an enterprise service bus (ESB).

    The security characteristics of these web services include digital certificates for transport level security two-way transport layer security (TLS),  message level security (encryption and digital signature) as well as single sign-on (SSO) based authentication using SAML 2.0 assertions.

    One of the challenges was to find a tool we could use to create test harness for these web services, but also to simulate and mock some of these same services during development and testing.

    For this I used soapUI. Overall it was not too complicated, except the support for SAML 2.0 since the current version of soapUI (4.0) only supports SAML 1.1 out-of-the-box.

    Initially security features on the XCPD web service were  turned off so we could test the basic SOAP web service functionalities. For this a new soapUI project was created by introspecting the XCPD service Web Services Description Language (WSDL) file:






















    To make the initial project simple, no test suite has been created and the initial operation has been re-labelled "RespondingGateway_XCPD" and its sample request has been modified to query a specific test patient (Joan Hunter) and renamed XCPD_PATIENT_JOAN_HUNTER:













    The test is done by submitting the request to the XCPD end-point:


































    This returns in the response window the XCPD response.

    In the next steps, we will setup all the security features for querying our XCPD service :
    The SAML 2.0 assertion will be described in the part two of this post.

    1. TLS setup

    First we need to indicate that we are using SSL on top of HTTP for the transport layer. For this we need to setup the client keystore via file/preference/SSL settings (from the machine where soapUI will run):


























    2. Message level security

    Probably the first thing you want is to specify your keystores and certificates if you decide to have mutal secure communication. You will use your private key from your key store (my_key_store.jks) to sign messages you send and decrypt the payloads you receive, and you will use specific server public key/certificate (a_another_server_keystore.jks) to encrypt the SOAP messages you send and verify signatures you receive. The server with whom you have secure mutual communication will do the reverse.














    The soapUI message level security configuration for SOAP (WS-security) can be setup by selecting our soapUI project XCPD_Tests, right-click and select Show Project View and then add using the sign + in the out-going WS-Security configuration :

     
























    You then specify your configurations (e.g. my_config_to_server_A) for outgoing messages and similarly to ingoing messages.

    Here how you would define a configuration in the Outgoing WS-security Configurations tab:

    1. add a signature tab a
    2. add an encryption tab (is you also use SAML 1.1 you would also add a SAML tab and a timestamp tab before adding the signature and the encryption).

































    2a. Signature

    In the Signature tab, you specify:
    • the keystore that contain the private key to sign the messages you are going to send (usually your private key - expect if you want to mock another server)
    • the alias for the key to use for signature
    • the certificate password
    • the key identifier type (none, binary security token, X509 certificate or subject key identifier)
    • the signature algorithm (e.g SHA256)
    • the signature canonicalization
    • the number of certificates used to sign
    • the parts you want to sign (e.g. the content of the body of namespace http://www.w3.org/2003/05/soap-envelope)




































        2b. Encryption


        In the Encryption tab, you specify:
        • the public key of the server you are sending your SOAP messages to
        • the alias for the key to use for encryption
        • the certificate password
        • the key identifier type (none, binary security token, Issuer Name and Serial, X509 certificate, subject key identifier, Embedded KeyInfo, Embedded SecurityToken Reference, Thumbprint SHA1 Identifier)
        • an embedded key name (if any)
        • an embedded key password (if any)
        • a symmetric encoding algorithm
        • a key encryption algorithm 
        • the encryption canonicalization
        • the number of certificates used to sign
        • the parts you want to encrypt (e.g. the content of the body of namespace http://www.w3.org/2003/05/soap-envelope)






































        And finally, last but not least, you need to specify for the request which outgoing security configuration you want to choose. In our case we have defined only one configuration: my_config_to_server_A at the project level. To select the configuration, click on the Auth Tab at the bottom of the request window, select in the drop-down Outgoing WSS field your configuration. Create and configuring incoming Secure Web Services will be very similar.













        You are now ready to test your SOAP Web Service with soapUI!

        In  part #2 we will look how SAML can be added to the mix.

        Thursday, April 28, 2011

        How to test harness REST web services with cURL




        cURL is a very convenient command line tool to send and retrieve data using the URL syntax. It supports a large number of protocols: HTTP, HTTPS, FTP, FTPS, SCP, SFTP, TFTP, LDAP, LDAPS, DICT, TELNET, FILE . IMAP, POP3, SMTP and RTSP.

        I have been using cURL for quickly and conveniently testing RESTFul APIs.

        Since I am doing most of my development on Windows platforms, I am using cURL in conjunction with Console, a Windows console window enhancement tool.

         First you need to download and install cURL for your platform (windows, Linux ect). Then you can do a quick test by accessible the home page of your favorite web site:









        This should display the HTML content of the home page. At this point I would suggest to look at the documentation to see what you can do with cURL including the FAQ.

        I usually use simple test harness such as 'curl http://www.acme.com/api/versions' if you REST API exposes available versions.

        You can then start to do more sophisticated tests such as authentication credentials from files (in my case I use a JSON data structure to automatically authenticate to my web service), saving cookies on files (using the the -c option):

        curl -c ./cookies.txt --data-binary @login_password.json -H "Content-Type: application/json"  http://www.acme.com/api/users/token

        With my JSON file as follow: {"login":{"username":"user1","password":"StrongPassword1"}} 

        The cookie in my case contains a session token that I can reuse between each cURL calls. In the next call I read the cookie (via the -b option):

        curl -b ./cookies.txt http://www.acme.com/api/users/userid1234567890/orders

        The output of the command can be saved in a file using the option -o or redirecting our output:

        curl -o google.html www.google.com

        or

        curl www.google.com > google.html 

        Enjoy!

        In my next post on this topic, I will explain how to use SSL/TLS and specify GZIP headers to your cURL requests.



        Thursday, March 31, 2011

        JUnit based integration testing with Simple JNDI



        I regularly use TJWS  a light weight Java Web Server build as a servlet container to provide standard Web Server capabilities at building and testing time.

        The main advantage is that I don't have to deploy my war file to my production server (e.g. JBoss) to test my Java Web application. My maven build runs complex integration JUnit tests immediately after building the war file with maven.

        In my configuration however, I have to use JNDI (Java Naming and Directory Interface) to connect to a specific datasource (DB2 via JDBC) for some of  my tests.

        I used Simple JNDI for this which also offer an easy and elegant way to configure data source access.

        Here are the steps I follow to setup my JUnit tests using Simple JNDI:

          • Add dependencies in Maven 2 Pom file for Simple JNDI, java persistence and DB2 JNDI/JDBC:
              
              <dependency>
                  <groupId>simple-jndi</groupId>
                  <artifactId>simple-jndi</artifactId>
                  <version>0.11.4.1</version>
                  <scope>test</scope>
              </dependency>
          
              <dependency>
                  <groupId>javax.persistence</groupId>
                  <artifactId>persistence-api</artifactId>
                  <version>1.0</version>
                  <scope>test</scope>
              </dependency>
            
              <dependency>
                  <groupId>com.ibm.db2</groupId>
                  <artifactId>db2jcc4</artifactId>
                  <version>9.7.0.2</version>
                  <scope>test</scope>
              </dependency>
              

          • Create a small Java class for the JNDI setup
               import javax.naming.InitialContext;
               import javax.sql.DataSource;
          
               public class JndiSetup { 
                   /**
                    * Setup the Data Source
                    */
                   public static void doSetup(String ds_name) {
                       try {
                           InitialContext ctxt = new InitialContext();
                           DataSource ds = (DataSource) ctxt.lookup("jdbc."+ds_name);
                           // rebind for alias if needed
                           ctxt.rebind("jdbc/"+ds_name, ds);
                       } catch (Exception ex) {
                           ex.printStackTrace();
                       }
                   }
               }

          In more complex situations, you may have also to create an EntityManager and use an EntityManagerFactory.

          • In the JUnit java script code, setup your JNDI connection before running your tests:
              @BeforeClass
               public static void setUpClass() throws Exception {
                    JndiSetup.doSetup("");
               }


          • Create a jndi.properties file in the "\src\test\resources" path in your project 
           
               java.naming.factory.initial=org.osjava.sj.SimpleContextFactory
               org.osjava.sj.root=target/test-classes/config
               org.osjava.jndi.delimiter=/
               org.osjava.sj.jndi.shared=true

          • Create a jdbc.properties file in the "\src\test\resources\config" path in your project (I am using an IBM DB2 data source). Create the config directory if it doesn't exist. The "config" name comes from org.osjava.sj.root parameter in jndi.properties file. If you want a different name, "foo", for the folder, make sure to update the "org.osjava.sj.root" property and create a "foo" folder in "\src\test\resources" path. Make sure the directory /src/test/resources is in the Java build path, and the output folder is set to target/test-classes
          
               <your-ds>.type=javax.sql.DataSource
               <your-ds>.driver=com.ibm.db2.jcc.DB2Driver
               <your-ds>.url=jdbc:db2://<your-database-host>:50000/<your-ds-or-ds-alias>
               <your-ds>.user=<your-db-login>
               <your-ds>.password=<your-db-password>

          With all of this you should be ready to test your integration using >mvn clean install.

          You may have also to do a >mvn eclipse:eclipse -DdownloadJavadocs=true as well if you are using Eclipse and your new dependencies and imports do not work properly.