Thursday, January 16, 2014

Accessing a non secured backend from a secured client with the help of WSO2 ESB

Assume that you have a backend that is not secured and you need to invoke this with a secured client. The below configuration is of a Proxy service which talks to a non secured backend. The client used to invoke this proxy service is secured. In this particular scenario, the Proxy service is secured.

Pre-requisites

Download WSO2 ESB 4.8.0 from here. Extract it to a folder of your choice and start the server.
Download the StockPurchasingService.aar from here and deploy it in a application server of your choice.

Testing out the scenario

When the message sent from the client is secured and the backend service is not, you need to ensure that the security headers are removed from the message before it is being sent from ESB to the backend. By using the header mediator as below, we can remove the security headers.




Step 1

Deploy the following proxy service in WSO2 ESB. <?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="secClientNonSecService"
       transports="https,http"
       statistics="disable"
       trace="disable"
       startOnLoad="true">
   <target>
      <inSequence>
         <header xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
                 name="wsse:Security"
                 action="remove"/>
      </inSequence>
      <outSequence>
         <send/>
      </outSequence>
      <endpoint>
         <address uri="http://localhost:9773/services/PuchasingService"/>
      </endpoint>
   </target>
   <publishWSDL uri="http://localhost:9773/services/PuchasingService?wsdl"/>
</proxy>

We will test our scenario with security scenario 2 (Non-repudiation). Once the above proxy service is deployed, apply security scenario 2 from the wizard.  View the ?wsdl of the proxy service and verify whether the relevant policy is attached to the proxy service.
 
One the security policy is applied, the complete proxy service configuration will look like what is available here.

Step 2

Create a Java project from your favourite IDE and place the SecurityClient.java & client.properties files in the below structure.

.
└── src
    ├── client.properties
    └── SecurityClient.java
 
Note: Download the resources.zip folder and extract the content to the src level. Then set the paths of following fields of the client.properties file accordingly.
  • clientRepo
  • clientKey
  • securityPolicyLocation
  • trustStore

Step 3

Invoke the SecurityClient.java code and you will get the expected response message as below.



Result :1000
Scenario No :2

Result : >ns:purchaseresponse xmlns:ns="http://service.purchasing.wso2.com"<>ns:return<1000>/ns:return<>/ns:purchaseresponse<

Friday, January 3, 2014

How to solve "PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target" issue of WSO2 Products


Ever come across the error message mentioned in the subject while trying out WSO2 products? Well, if you have, the reason is that cetifacte of the backend that you is not trusted and the certificate of that backend server should be added to the WSO2 product servers client-truststore.jks. Lets try this with a simple example.

Assume you have a simple API with the below configuration pointing to twitter search in WSO2 ESB (You can try this with a latest version of ESB). The configuration will be as follows.

      <api name="TwitterAPI" context="/twitter">
      <resource methods="GET" url-mapping="/*">
         <inSequence>
            <send>
               <endpoint>
                  <address uri="https://twitter.com"/>
               </endpoint>
            </send>
         </inSequence>
         <outSequence>
            <send/>
         </outSequence>
      </resource>
   </api>

Invoke the above API using the below command.

curl -v -X GET -H "Content-type: application/json" http://localhost:8281/twitter/search?q=wso2

It will throw the below exception at the WSO2 ESB server console.


Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
    at sun.security.validator.Validator.validate(Validator.java:260)
    at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:283)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:138)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1328)
    ... 17 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
    ... 23 more



Inorder to get rid of this exception and the request to passthrough successfully to the backend, you need to import the public certificate of Twitter to the client-truststore.jks of the WSO2 ESB server instance. Below are the steps you need to follow.

1. Go to https://twitter.com/, click on the lock icon at the address bar, click on the 'Connection' tab, then click on the link 'Certificate Information'. From the 'Certificate Viewer', select the tab 'Details' and click on the 'Export' button and download the certificate (twitter.com) to a preferred location.

2. Once downloaded, issue the below command to import the public certificate of Twitter to the client-truststore.jks.

$ keytool -importcert -file $somepath/twitter.com -keystore $ESB_HOME/repository/resources/security/client-truststore.jks -alias "Twitter"

3. Restart the WSO2 ESB server and invoke the API again and you will get the expected result.