Saturday, October 31, 2015

WSO2 Gateway (WSO2 GW) -Alpha

WSO2 Gateway (WSO2 GW) is an ultra high performance, lightweight and configuration-driven message gateway based on
standard gateway pattern. It aims to encapsulate messaging between source and target systems that are built with
disparate technologies, protocols, and standards. While it includes messaging between two systems, message mediation
can be controlled by configuring WSO2 GW’s mediation logic.

Download Aplha


Key Features

* Ultra high performance and low latency  HTTP/S messaging.

* Supports thousands of concurrent connections/clients.

* Header-based routing using Apache Camel as the message mediation engine.

* Defines REST services/APIs using Camel REST DSL.

* Lightweight and stateless service orchestration.

* Load balancing and failover messaging.

* Error handling support.

Getting Started

By configuring the [camel-context.xml](https://github.com/wso2/product-gw/blob/master/product/carbon-home/repository/conf/camel/camel-context.xml) (which can be found in `$CARBON_HOME/repository/conf/camel/camel-context.xml`)
we can achieve camel routing.

Sample camel configuration for Header-based routing

    <route id="http-routes">
        <from uri="wso2-gw:/default"/>
        <choice>
            <when>
                <simple>${header.routeId} regex 'r1'</simple>
                <to uri="wso2-gw:http://localhost:9000/services/SimpleStockQuoteService"/>
            </when>
            <when>
                <simple>${header.routeId} regex 'r2'</simple>
                <to uri="wso2-gw:http://localhost:9002/service/SimpleStockQuoteService"/>
            </when>
            <otherwise>
                <to uri="wso2-gw:http://localhost:9004/SimpleStockQuoteService"/>
            </otherwise>
        </choice>
    </route>
```

 Sample request to route to localhost:9000
 curl  http://localhost:9090/default -H __"routeId:r1"__

 If we don't have any routeId header the request will be routed to the localhost:9004 (i.e to otherwise)

Sampel REST configuration

Following is a sample rest interface definition
```
    <rest path="/gw">
        <get uri="/news">
            <to uri="direct:getNews"/>
        </get>
        <get uri="/news/{id}">
            <to uri="direct:getNewsById"/>
        </get>
    </rest>
```

and follwoing is the corresponding routes
```
    <route>
        <from uri="direct:getNews"/>
        <to uri="wso2-gw:http://jsonplaceholder.typicode.com/posts"/>
    </route>
    <route>
        <from uri="direct:getNewsById"/>
        <recipientList>
            <simple>wso2-gw:http://jsonplaceholder.typicode.com/posts/${header.id}</simple>
        </recipientList>
    </route>
```

when we invoke the request `http://localhost:9090/gw/news`
it will be routed to `http://jsonplaceholder.typicode.com/posts`

similarly `http://localhost:9090/gw/news/24` will be routed to `http://jsonplaceholder.typicode.com/posts/24`

Monday, June 15, 2015

Connecting IBM MQ with WSO2 ESB via SSL (Mutual Authentication)

Thought of writing this blog because very recently we a had use-case to demonstrate this particular features, but not like other MQ, IBM MQ gave us a hard time to figure out and fix the puzzle. On the other hand WSO2 ESB to MQ connection via SSL quite important and the most trick part is to learn the materials provided by IBM, this blog covers connecting IBM MQ 8.0 with Fix pack released for MQ SSL related issues MQ 8.0.0.2 please find the detail [2][4]


  • First tricky part is to define a certificate repository correctly best way learn this is to study [1], please find the  key repository detail I have configured.

  • Once you do that, next most important part is setting key repositories to MQ connection managers, you need to give the path in which the key repository has stored





  • Then you need to follow the same procedure to create connection with .binding  [3]
  • Once do that you need to provide the SSL cipher spec which suppose to use there are few algorithms but remember that with IBM MQ 8.0 onwards SSL V3 support is deprecated thus you need to use the latest java client libraries to connect the queue.
  • Please read [5] the changes that accommodated in IBM MQ 8.0

  • There were lots of class loader issues, it was due to MQ 7.0.0 client libraries conflict and we have created new OSGI jar bundle to resolve this puzzle, please find the latest jars which you must put in ESB dropping folder and make sure only those two jars only required for connect latest MQ 8.0 otherwise you will get tons of connection related issues.
  • Then when you start ESB you need to include the cipher spec as environment variable, please make sure to modify wso2servers.sh with  
    • -DCMQC.SSL_CIPHER_SUITE_PROPERTY="SSL_RSA_WITH_3DES_EDE_CBC_SHA" \ 


[1] http://www.ibm.com/developerworks/websphere/library/techarticles/0510_fehners/0510_fehners.html
[2] http://www-01.ibm.com/support/docview.wss?uid=swg24039436
[3] http://nandikajayawardana.blogspot.com/2015/03/configuring-ibm-mq-with-wso2-esb.html
[4] https://www.ibm.com/developerworks/community/blogs/messaging/entry/bitesize_blogging_mq_v8_fix_pack_8_0_0_2_mq_classes_now_support_tls_with_the_oracle_jre?lang=en
[5] http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.pro.doc/q001060_.htm

Friday, May 8, 2015

NTLM Authentication WSO2 ESB (Developer Testing)

NTLM ?

Thought of writing this blog as I got few queries on how ESB can be configured to communicate services which are secured with NTLM (which is also is known as Windows Authentication), please refer [1] to learn more information on NTLM
  When comes with WSO2 ESB we do not have OOTB approach to resolve this puzzle, we have tried  to add pass-through support for NTLM. But, there seems to be inherent technical problems in NTLM standard it self preventing it to work through a proxy.
NTLM is connection oriented, based on connection state. It authenticates the connection - not really the end user.
Kerberos is the preferred choice to connect through proxy servers than NTLM, due to the connection-based nature of NTLM.
When a client needs to authenticate itself to a proxy or server using the NTLM scheme then the following 4-way handshake takes place
1: C -> S GET ...
2: S -> C 401 Unauthorized
WWW-Authenticate: NTLM
3: C -> S GET ...
Authorization: NTLM <type-1-message>
4: S -> C 401 Unauthorized
WWW-Authenticate: NTLM <type-2-message>
5: C -> S GET ...
Authorization: NTLM <type-3-message>
6: S -> C 200 Ok
This manifests itself states that the network connection must be kept alive during the second part of the handshake,i.e. between the receiving of the type-2 message from the server (step 4) and the sending of the type-3 message (step 5). Each time the connection is closed this second part (steps 3 through 6) must be repeated over the new connection (i.e. it's not enough to just keep sending the last type-3 message).
Also, once the connection is authenticated, the Authorization header need not be sent anymore while the connection stays open, no matter what resource is accessed.
Microsoft also emphasizes that NTLM requires implicit end-to-end state and will not work through a proxy server.
So how we have overcome
  since we need to maintain "NTLM is connection oriented, based on connection state.", the solution we came is to use Class Mediator and CalloutMediator approach

Ok, lets start from the beginning, (for novice users this might helpful as I will go through setting up NTLM service from VM which has Windows 7)

Setup NTLM service in Windows

  • (Assume you have installed IIS service from windows features), Then need to enable Windows Authentication



  • Then you need to navigate to IIS admin service and enable Windows authentication for a selected site





  • Since this a developer testing, I will create a WCF service and host the created service under IIS



  • When you try to deploy the created WCF service from Microsoft Visual Studio few errors can be thrown and there are solutions being discussed under [2][3]
    • Config Error: This configuration section cannot be used at this path. This happens when the section is locked at a parent level. Locking is either by default (overrideModeDefault="Deny"), or set explicitly by a location tag with overrideMode="Deny" or the legacy allowOverride="false".
    • The authentication schemes configured on the host ('IntegratedWindowsAuthentication') do not allow those configured on the binding 'BasicHttpBinding' ('Anonymous'). Please ensure that the SecurityMode is set to Transport or TransportCredentialOnly. Additionally, this may be resolved by changing the authentication schemes for this application through the IIS management tool, through the ServiceHost.Authentication.AuthenticationSchemes property, in the application configuration file at the element, by updating the ClientCredentialType property on the binding, or by adjusting the AuthenticationScheme property on the HttpTransportBindingElement
  • If you successfully deploy service then when accessing the service it should look as



  • If you enter invalid Windows Credentials result would be



  • Successful invocation will results as




Setup WSO2 ESB
  • HttpClient has improved NTLM support please refer [4] for the relevant technical detail
  • Written simple client to test NTLM communication, client can be found from here

    • Invalid Request




  • And we have written a class mediator by referring the same NTLMClient i.e NTLMMediator, and once download you need to compile to OSGI jar then need to place at ESB_HOME/repository/components/dropins then restart server.
  • Since we do use proxy and Callout mediator approach the synapse configuration looks like give below.
  • If you setup everything correctly and when invoke ESB proxy then it will return result as 

<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="NTLMProxy"
       transports="https http"
       startOnLoad="true"
       trace="disable">

   <target faultSequence="fault">
      <inSequence>
         <class name="org.wso2.carbon.mediator.ntlm.NTLMMediator">
            <property name="username" value="ayash"/>
            <property name="host" value="xxx"/>
            <property name="domain" value="yyy"/>
            <property name="password" value="mmmm"/>
         </class>

         <class name="org.wso2.carbon.mediator.ntlm.NTLMCalloutMediator">
            <property name="serviceURL" value="http://xxxxx:8080/Service1.svc"/>
            <property name="initAxis2ClientOptions" value="false"/>
            <property name="action" value="http://tempuri.org/IService1/GetData"/>
         </class>

         <header name="To" action="remove"/>
         <property name="RESPONSE" value="true" scope="default" type="STRING"/>
         <property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
         <send/>
      </inSequence>
   </target>
</proxy>







You could give a try on this. Its a very basic developer test for NTLM and can be enhanced many ways based on requirements.


[1] https://msdn.microsoft.com/en-us/library/windows/desktop/aa378749%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
[2] http://stackoverflow.com/questions/9794985/iis-this-configuration-section-cannot-be-used-at-this-path-configuration-lock
[3] http://stackoverflow.com/questions/15264969/make-wcf-service-integratedwindowsauthentication
[4] https://hc.apache.org/httpcomponents-client-ga/ntlm.html

Tuesday, March 17, 2015

Federated Authentication-Configure WSO2 IS with Salesforce


This article will discuss how we could configure WSO2 Identity server with salesforce for Federated Authentication
  • You should create a salesforce developer account from https://developer.salesforce.com/
  • Once you login to developer account you need to navigate, Identity providers under Security console tab

  • Then you must download Salesforce public certificate and the Identity provide meta-information which is required for IDP configuration WSO2 IS
    <md:entitydescriptor entityid="https://wso2idc-dev-ed.my.salesforce.com" validuntil="2025-03-18T00:16:43.800Z" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
       <md:idpssodescriptor protocolsupportenumeration="urn:oasis:names:tc:SAML:2.0:protocol">
          <md:keydescriptor use="signing">
             <ds:keyinfo>
                <ds:x509data>
                   
                </ds:x509data>
             </ds:keyinfo>
          </md:keydescriptor>
          <md:nameidformat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:nameidformat>
          <md:singlesignonservice binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" location="https://wso2idc-dev-ed.my.salesforce.com/idp/endpoint/HttpPost">
          <md:singlesignonservice binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" location="https://wso2idc-dev-ed.my.salesforce.com/idp/endpoint/HttpRedirect">
       </md:singlesignonservice></md:singlesignonservice></md:idpssodescriptor>
    </md:entitydescriptor>
  •  You will find POST and HTTP re-directing IDP urls are at the meta-information which required when configuring WSO2 Identity Provider.
  • Then you need to create a Connected app, you need to provide almost similar entries when creating connected app, specially pay special attention on ACS URL and Issuer URL



  • Then create a user profile and add connected app where only the user who has the profile will allow to authenticate via SSO


  • Start Identity server then configure Identity Provider as shown below, you need to import salesforce public certificate obtained in earlier steps as below.




  • Configure Service provider as shown below,



  • Inbound configuration should be as below

  • Then deploy travolocity app , setup SSO then click login page











Monday, February 23, 2015

Identity Server 5.0 User Account Recovery / User Account lock and unlocking


This article I'm gonna discuss about account registration methods, for the demo purpose I am going to use WSO2 IS 5.0.0 , InfomationRecovery sample (shared here with) which is hosted in Tomcat

Setting up IS 5.0.0
  • Update below parameters  wso2is-5.0.0\repository\conf\security\identity-mgt.properties
Identity.Listener.Enable=true
Notification.Sending.Enable=true
Notification.Expire.Time=7200
Notification.Sending.Internally.Managed=true
Authentication.Policy.Enable=true
Authentication.Policy.Account.Lock.On.Failure=true
Authentication.Policy.Account.Lock.On.Failure.Max.Attempts=2
Authentication.Policy.Account.Lock.Time=2

  • You need to configure the email sender and here we use the axis transport Sender. Following configureation needs to be done in the axis2.xml file located in the Identity Server installation under <is_home>/repository/conf/axis2 directory. Uncomment the following and give your email details.

<transportsender class="org.apache.axis2.transport.mail.MailTransportSender" name="mailto">
<parameter name="mail.smtp.from">wso2demomail@gmail.com</parameter> 
        <parameter name="mail.smtp.user">wso2demomail@gmail.com</parameter> 
        <parameter name="mail.smtp.password">mailpassword</parameter> 
        <parameter name="mail.smtp.host">smtp.gmail.com</parameter> 
        <parameter name="mail.smtp.port">587</parameter> 
        <parameter name="mail.smtp.starttls.enable">true</parameter> 
        <parameter name="mail.smtp.auth">true</parameter> 
</transportsender>
  • You also can configure the email format and confirmation code urls in the email-admin-config.xml under <is_home>/repository/conf/email directory. For password recovery sending email you need to have a email template type as “passwordReset”. Following shows a sample configuration.

  • Start IS server
  • Map Account Recovery Clam as given below



  • Start Tomcat or any Application server, deploy war file (project can be found from here)
  • Click user registration




















  • Configure IS for SP please see image






















  • Once click from Registration will be direct to SSO page








































  • Recover password if forgot..
































Tuesday, February 17, 2015

SAML2 bearer tokens with OAuth2 tokens in WSO2 API Manager


   Most of enterprise applications use SAML2 to engage a third-party identity provider to grant access to systems that are only authenticated against the enterprise application. These enterprise applications might need to consume OAuth-protected resources through APIs, after validating them against an OAuth2.0 authentication server. However, an enterprise application that already has a working SAML2.0 based Single Sign On infrastructure between itself and the IDP prefers to use the existing trust relationship, even if the OAuth authorization server is entirely different from the IDP. The SAML2 Bearer Assertion Profile for OAuth2.0 helps leverage this existing trust relationship by presenting the SAML2.0 token to the authorization server and exchanging it to an OAuth2.0 access token and then use that OAuth token to get access to APIs.



Ground work Understanding how this process can be implemented


  • Setup IDP in WSO2 Identity server (Uses IS 5.0.0)








  • Register a subscriber (user) in API-M


  • Now need to request SAML token for the user, for that have created a script as follows, make sure the SAML request being signed using the public certificate.

#!/bin/bash

#saml assertion issuer
ISSUER="SAML_ASSERTION_TEST_ISSUER"
#ISSUER="localhost"
#saml2_assertion_subject
SUBJECT="saman123"
#saml2_assertion_recipient
RECIPIENT="https://localhost:9444/oauth2/token/"
#saml2_asseertion_audience_restriction
AUDIENCE="https://localhost:9444/oauth2/token/"
#path to JKS store file
JKS_PATH="/Users/dushan/workspace/poc/apikeym/apim17/wso2is-5.0.0/repository/resources/security/wso2carbon.jks"

java -jar SAML2AssertionCreator/SAML2AssertionCreator.jar $ISSUER $SUBJECT $RECIPIENT $AUDIENCE $JKS_PATH wso2carbon wso2carbon wso2carbon



  • You can download SAML2AssertionCreator project from here
  • Exchange SAML token to Access Token
curl -k -d "grant_type=urn:ietf:params:oauth:grant-type:saml2-bearer&assertion=<SAML_ASSERTION obtained from above step >&scope=PRODUCTION" -H "Authorization: Basic <base 64[consumer_key:consumer_secret] of desired API, Content-Type: application/x-www-form-urlencoded" https://localhost:8243/token





Setting Proxy with mod_proxy with Basic Authorization

Install mod_proxy and setup reverse proxy in Apache Webserver

Follow the given below steps.
Note: In all given below example replace the value of ServerAdmin,ServerName & ServerAlias as per your server information

Step 1: Install the module

sudo apt-get install libapache2-mod-proxy-html

Step 2: Installing the dependency libxml2-dev

apt-get install libxml2-devStep 3: Load the module

a2enmod proxy proxy_http

Step 4: Create the Virtual Host in apache configuration file . If your configuration is located in conf.d you have to do changes in that file. I am giving example with default setting in Apache Webserver in Ubuntu

vi /etc/apache2/sites-enabled/000-default

Step 5: Following configuration allows user to access http service but it requires user to provide credentials, which is stored at /var/www/.htpasswd


<VirtualHost *:80>
ServerName 192.168.56.102
SSLEngine off
ProxyPass /foo/ http://192.168.56.1:8280/
<Proxy *>
Order Allow,Deny
Allow from all
AuthType Basic
AuthName "Authenticated proxy"
AuthUserFile /var/www/.htpasswd
Require valid-user
</Proxy>
</VirtualHost>







Step 6: Accessing https services, which requires to generate key pair of wso2carbon server and store as SSLCertificateFile/SSLCertificateKeyFile

generate key pair from wso2carbon.jks

keytool -importkeystore -srckeystore keystore.jks -destkeystore keystore.p12 -deststoretype PKCS12 -srcalias <jkskeyalias> -deststorepass <password> -destkeypass <password>
Export certificate.


openssl pkcs12 -in keystore.p12 -nokeys -out cert.pem
Export unencrypted private key.


openssl pkcs12 -in keystore.p12 -nodes -nocerts -out key.pem


Optional disabling CN check.

SSLProxyCheckPeerName off
SSLProxyCheckPeerCN off<VirtualHost *:443>
SSLProxyEngine On
SSLCertificateFile /home/dushan/cert.pem
SSLCertificateKeyFile /home/dushan/key.pem


SSLProxyCheckPeerName off
SSLProxyCheckPeerCN off
# CacheDisable *


SSLEngine on
ProxyPass /foo/ https://192.168.56.1:8243/


<Proxy *>
Order Allow,Deny
Allow from all
AuthType Basic
AuthName "Authenticated proxy"
AuthUserFile /var/www/.htpasswd
Require valid-user
</Proxy>


</VirtualHost>

Sunday, February 8, 2015

Secure File Transfer with VFS (ESB FTP+SSL certificates)



Hello, everyone this post I would discuss a new feature that enables us to share files between ESB and FTP server where FTP server establish connection through SSL certificates. will go step by step discussing how you could prepare FTP server to enable SSL and then share files between ESB
  • Generating KeyPair
    • openssl genrsa -des3 -out dushan.key 1024
    • openssl req -new -x509 -days 365 -key dushan.key -out dushan.crt
    • Import certificate to ESB client-trust store 
      • keytool -import -alias stan  -keystore client-truststore.jks -file dushan.crt

  • Used Filezilla client and server to demonstrate this scenario, 




  • You can configure VFS transport with https://docs.wso2.com/pages/viewpage.action?pageId=26838852
  • Proxy Configuration looks as below
    • Please notice the configuration (special notations) 'vfs.ssl.keystore' ,'vfs.ssl.truststore' ,'vfs.ssl.tspassword','vfs.ssl.kspassword'
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="VFSProxy"
       transports="vfs"
       statistics="disable"
       trace="disable"
       startOnLoad="true">
   <target>
      <inSequence>
         <property name="OUT_ONLY" value="true"/>
         <property name="transport.vfs.ReplyFileName"
                   expression="fn:concat(fn:substring-after(get-property('MessageID'), 'urn:uuid:'), '.csv')"
                   scope="transport"/>
         <property name="messageType" value="text/plain" scope="axis2"/>
         <property name="ClientApiNonBlocking" scope="axis2" action="remove"/>
         <send>
            <endpoint>
               <address uri="vfs:ftps://dushan:12345@192.168.56.102/test?vfs.ssl.keystore=/Users/dushan/workspace/onlinesupport/ESB/wso2esb-4.8.1/repository/resources/security/wso2carbon.jks&amp;vfs.ssl.truststore=/Users/dushan/workspace/onlinesupport/ESB/wso2esb-4.8.1/repository/resources/security/client-truststore.jks&amp;vfs.ssl.kspassword=wso2carbon&amp;vfs.ssl.tspassword=wso2carbon&amp;vfs.ssl.keypassword=wso2carbon"/>
            </endpoint>
         </send>
         <drop/>
      </inSequence>
   </target>
   <parameter name="transport.PollInterval">10</parameter>
   <parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter>
   <parameter name="transport.vfs.FileURI">file:///Users/xx/in</parameter>
   <parameter name="transport.vfs.MoveAfterProcess">file:///Users/xx/processed</parameter>
   <parameter name="transport.vfs.MoveAfterFailure">file:///Users/xx/fail</parameter>
   <parameter name="transport.vfs.FileNamePattern">.*.csv</parameter>
   <parameter name="transport.vfs.ContentType">text/plain</parameter>
   <parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
   <description>Custom file reader proxy for CAP mainframe file. This will perform transformation to DP v2 structure and store data into Vertica</description>
</proxy>

  • Fail to add public certificates would result errors as follows
... 16 more 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:231) at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1421) ... 27 more Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target