Friday, January 3, 2014

Working with WSO2 ESB Tasks with 'injectTo' property

WSO2 ESB Tasks allows to run scheduled jobs at specified intervals which is triggered by a timer. In this blog post I discuss about how to use 'injectTo' property with tasks.

Injecting the message to a proxy service:

Basic structure as follows:
<property xmlns:task="http://www.wso2.org/products/wso2commons/tasks"
name="injectTo"
value="proxy"/>
.......................
<property xmlns:task="http://www.wso2.org/products/wso2commons/tasks"
name="proxyName"
value="SampleProxy"/>

  1. Use the configuration below
  2. Start inbuilt backend service 'axis2serever' at $ESB_HOME/samples/axis2Server
  3. Here I use SimplestockQuoteService and you need to built it by running ant command at $ESB_HOME/samples/axis2Server/src/SimpleStockQuoteService
  4. Retart ESB and see task triggered 2 times withing 5ms as per below example:
    <trigger count="2" interval="5"/> 

 <?xml version="1.0" encoding="UTF-8"?>  
 <definitions xmlns="http://ws.apache.org/ns/synapse">  
   <registry provider="org.wso2.carbon.mediation.registry.WSO2Registry">  
    <parameter name="cachableDuration">15000</parameter>  
   </registry>  
   <proxy name="SampleProxy"  
      transports="https http"  
      startOnLoad="true"  
      trace="disable">  
    <description/>  
    <target endpoint="A">  
      <inSequence>  
       <log>  
         <property name="LOG"  
              value="======================================================="/>  
       </log>  
      </inSequence>  
      <outSequence>  
       <log>  
         <property name="LOG" value="******************************************"/>  
       </log>  
      </outSequence>  
    </target>  
   </proxy>  
   <endpoint name="A">  
    <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>  
   </endpoint>  
   <sequence name="fault">  
    <log level="full">  
      <property name="MESSAGE" value="Executing default 'fault' sequence"/>  
      <property name="ERROR_CODE" expression="get-property('ERROR_CODE')"/>  
      <property name="ERROR_MESSAGE" expression="get-property('ERROR_MESSAGE')"/>  
    </log>  
    <drop/>  
   </sequence>  
   <sequence name="main">  
    <in>  
      <log level="full"/>  
      <filter source="get-property('To')" regex="http://localhost:9000.*">  
       <send/>  
      </filter>  
    </in>  
    <out>  
      <send/>  
    </out>  
    <description>The main sequence for the message mediation</description>  
   </sequence>  
   <task name="SampleInjectToSequenceTask"  
      class="org.apache.synapse.startup.tasks.MessageInjector"  
      group="synapse.simple.quartz">  
    <trigger count="2" interval="5"/>  
    <property xmlns:task="http://www.wso2.org/products/wso2commons/tasks" name="message">  
      <m0:getQuote xmlns:m0="http://services.samples">  
       <m0:request>  
         <m0:symbol>IBM</m0:symbol>  
       </m0:request>  
      </m0:getQuote>  
    </property>  
    <property xmlns:task="http://www.wso2.org/products/wso2commons/tasks"  
         name="proxyName"  
         value="SampleProxy"/>  
    <property xmlns:task="http://www.wso2.org/products/wso2commons/tasks"  
         name="injectTo"  
         value="proxy"/>  
   </task>  
 </definitions>  




Injecting the message to a proxy service:


Basic structure as follows:
<property xmlns:task="http://www.wso2.org/products/wso2commons/tasks"
name="injectTo"
value="sequence"/>
.......................
<property xmlns:task="http://www.wso2.org/products/wso2commons/tasks"
name="sequenceName"
value="SampleSequence"/>

  1. Use the configuration below.
  2. Same axis2service and SimpleStokQuote service can be used as per above
  3. Retart ESB and see task triggered 3 times withing 10ms as per below example:
    <trigger count="3" interval="10"/>
 <?xml version="1.0" encoding="UTF-8"?>  
 <definitions xmlns="http://ws.apache.org/ns/synapse">  
   <registry provider="org.wso2.carbon.mediation.registry.WSO2Registry">  
    <parameter name="cachableDuration">15000</parameter>  
   </registry>  
   <proxy name="SampleProxy"  
      transports="https http"  
      startOnLoad="true"  
      trace="disable">  
    <description/>  
    <target endpoint="A">  
      <inSequence>  
       <log>  
         <property name="LOG"  
              value="======================================================="/>  
       </log>  
      </inSequence>  
      <outSequence>  
       <log>  
         <property name="LOG" value="******************************************"/>  
       </log>  
      </outSequence>  
    </target>  
   </proxy>  
   <endpoint name="A">  
    <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>  
   </endpoint>  
   <sequence name="fault">  
    <log level="full">  
      <property name="MESSAGE" value="Executing default 'fault' sequence"/>  
      <property name="ERROR_CODE" expression="get-property('ERROR_CODE')"/>  
      <property name="ERROR_MESSAGE" expression="get-property('ERROR_MESSAGE')"/>  
    </log>  
    <drop/>  
   </sequence>  
   <sequence name="recSeq">  
    <log level="full">  
      <property name="MSG" value="===== RESPONSE ====="/>  
    </log>  
    <drop/>  
   </sequence>  
   <sequence name="SampleSequence">  
    <send receive="recSeq">  
      <endpoint>  
       <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>  
      </endpoint>  
    </send>  
   </sequence>  
   <sequence name="main">  
    <in>  
      <log level="full"/>  
      <filter source="get-property('To')" regex="http://localhost:9000.*">  
       <send/>  
      </filter>  
    </in>  
    <out>  
      <send/>  
    </out>  
    <description>The main sequence for the message mediation</description>  
   </sequence>  
   <task name="SampleInjectToSequenceTask"  
      class="org.apache.synapse.startup.tasks.MessageInjector"  
      group="synapse.simple.quartz">  
    <trigger count="3" interval="10"/>  
    <property xmlns:task="http://www.wso2.org/products/wso2commons/tasks"  
         name="injectTo"  
         value="sequence"/>  
    <property xmlns:task="http://www.wso2.org/products/wso2commons/tasks" name="message">  
      <m0:getQuote xmlns:m0="http://services.samples">  
       <m0:request>  
         <m0:symbol>IBM</m0:symbol>  
       </m0:request>  
      </m0:getQuote>  
    </property>  
    <property xmlns:task="http://www.wso2.org/products/wso2commons/tasks"  
         name="sequenceName"  
         value="SampleSequence"/>  
   </task>  
 </definitions>  

Thursday, January 2, 2014

SAML2.0 Assertion with WSO2 Identity Server


In this blog post I will discuss the steps forCreating SAML2.0 Bearer Assertion profile for OAuth 2.0 with WSO2 Identity Server”.

  1. Download latest IS release from http://wso2.com/products/identity-server/.
    (Here I use WSO2 IS 4.6.0 since it is the latest release at the time of writing this blog post.)
  2. Create a SAML2 Assertion. You can use the command line client program (SAML2AssertionCreator) from here. Extract the ZIP file and navigate to the lib folder and execute the following command in the command linejava -jar SAML2AssertionCreator.jar <issuer> <username> <recipient> <requestedAudiences> <keyStoreFile> <keyStorePassword> <alias> <privateKeyPassword> <comma seperated user calimvalue pairs(claim:value)>
    ex:
    java -jar SAML2AssertionCreator.jar SAML2AssertionCreator shashika https://localhost:9443/oauth2/token https://localhost:9443/oauth2/token /home/shashika/Downloads/saml-oauth/wso2is-4.6.0/repository/resources/security/wso2carbon.jks wso2carbon wso2carbon wso2carbon FirstName|shashika,LastName|Ubhayaratne,Country|SriLanka


Note the “base64-url Encoded Assertion String” from the reply above and copy the part “PD.......3D”. This needs to be used in step 5.
  1. Register new Trusted Identity Provider.
  • Go to Configure -> Trusted Identity Providers.
  • Click on ‘Add New Trusted Identity Provider’.
  • Enter a unique identifier for this Trusted Identity Provider across the tenant.
    ex :
  • Identity Provider Name: sampleidp
  • Identity Provider Issuer: SAML2AssertionCreator
  • Identity Provider Public Certificate: << attach the certificate “wso2pem.pem” >> (You can generate this public certificate using kytool: (keytool -export -alias wso2cert -file wso2pem.pem -keystore wso2carbon.jks)
  • Identity Provider Audience: https://localhost:9443/oauth2/token


  1. Create a new OAuth2.0 application under Main -> Manage -> OAuth
    SAML should be selected as “Allowed Grant Types”.
  2. Execute the following HTTP request to the https://localhost:9443/oauth2/token endpointcurl -X POST -k -u "<Client Id>:<Client Secret>" -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" -d "grant_type=urn:ietf:params:oauth:grant-type:saml2-bearer&scope=openid&assertion=<base64-url Encoded Assertion from step 2>" https://localhost:9443/oauth2/token/
    curl -X POST -k -u "noEnn5tvU5tgEJfHImicSApBMAwa:RMauKZY7H1GAWFJ77vffMI8Pv9ka" -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" -d "grant_type=urn:ietf:params:oauth:grant-type:saml2-bearer&scope=openid&assertion=PD94bWwg<<.....>>9uPg%3D%3D" https://localhost:9443/oauth2/token/
    Note: assertion=PD94bWwg<<.....>>9uPg%3D%3D. This should be taken from Step2.
  3. In the response from above step you will get the base64 encoded id token
    ex: {"token_type":"bearer","expires_in":481,"refresh_token":"71df5c5a5ca2b6dc84c2cf2d64183342","id_token":"eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0=\r\n.eyJleHAiOi0zNzcyNjI5NywiYXpwIjoiZklFa1p0aW5yYnBMQlh4WDgzbXdEekNQOEFBYSIsInN1\r\nYiI6ImlzaGFyYSIsImF1ZCI6ImZJRWtadGlucmJwTEJYeFg4M213RHpDUDhBQWEiLCJpc3MiOiJo\r\ndHRwczpcL1wvbG9jYWxob3N0Ojk0NDNcL29hdXRoMmVuZHBvaW50c1wvdG9rZW4iLCJGaXJzdE5h\r\nbWUiOiJJc2hhcmEiLCJMYXN0TmFtZSI6IkthcnVuYXJhdGhuYSIsIkNvdW50cnkiOiJTcmlMYW5r\r\nYSIsImlhdCI6LTQxMzI2Mjk3fQ==\r\n.","access_token":"466d19d052acd21aec3ce045cb46329b"}

  4. Decoding the id_token value you can get the user claims. (Id token contains two values separated by '.')
    Refer bold part from the response, Remove “/r/n” parts and paste it on decoder.
    Go to “http://www.base64decode.org/
    Paste the copied text here.
    Text should be prepared as follows: eyJleHAiOi0zNzcyNjI5NywiYXpwIjoiZklFa1p0aW5yYnBMQlh4WDgzbXdEekNQOEFBYSIsInN1YiI6ImlzaGFyYSIsImF1ZCI6ImZJRWtadGlucmJwTEJYeFg4M213RHpDUDhBQWEiLCJpc3MiOiJo\r\ndHRwczpcL1wvbG9jYWxob3N0Ojk0NDNcL29hdXRoMmVuZHBvaW50c1wvdG9rZW4iLCJGaXJzdE5hbWUiOiJJc2hhcmEiLCJMYXN0TmFtZSI6IkthcnVuYXJhdGhuYSIsIkNvdW50cnkiOiJTcmlMYW5rYSIsImlhdCI6LTQxMzI2Mjk3fQ==
    Decoded String:
    {"exp":170653649,"azp":"noEnn5tvU5tgEJfHImicSApBMAwa","sub":"shashika","aud":"noEnn5tvU5tgEJfHImicSApBMAwa","iss":"https:\/\/localhost:9443\/oauth2endpoints\/token","FirstName":"shashika","LastName":"ubhayaratne","Country":"SriLanka","iat":167053649}