Monday, August 22, 2016

Introduction to configure SAML SSO in web applications with WSO2 Identity Server

SSO is the process of an application requesting for authentication credentials from an identity provider system. This type of systems will establish user identity for once and then share it across the sub systems.  
Simply saying SSO systems allow users to log in once using a single id and a password and gain access to multiple systems without having to log into them individually.
There are different protocols used in SSO services such as Keberos and Security Assertion Markup Language (SAML). Here I have discussed how to do it using SAML 2.0. SAML is in XML standards. It facilitates exchanging user authentication data across secure domains.
There are three main components in SAML based SSO services.
  1. User
  2. Identity provider
  3. Service provider (Web application)
SSO process
samlSSOprocess (2).png


  1. User tries to access the web application. It is deployed in WSO2 AS.
  2. Web application which acts as the service provider generates a SAML request.And there is a predefined SSO url in web application.
  3. It will then redirect the browser to SSO url with the encoded SAML request.
  4. Then browser will be redirected to SSO url which is going to be an instance of the identity provider created in WSO2 identity server.
  5. IS will then parse the SAML request. Check whether there is an already logged in user session. If not authenticate the user by asking their usernames and passwords
  6. IS will then generate the encoded SAML response which includes the username and user’s claims.
  7. Then it will redirect the browser to ACS with the generated SAML response.
  8. Browser will send the SAML response to ACS url. ACS url is the place where service provider receives assertions for the sent SAML requests.
  9. ACS will decode the  SAML response and validate it. Then will decide whether to grant or deny access to that user.
  10. User will be granted or denied access to the web application.

Wednesday, August 17, 2016

[WSO2 ESB] Use of Local Entries.

In this post I would like to discuss about the importance of local entries used in WSO2 ESB. Local entry is a memory registry.

Assume that you have an element which is used inside the XML configuration in a proxy service or sequence. And the value of this element needs to be changed time to time. In a case like this if you insert this in a local entry you can easily edit, delete or add values to that without changing the entire code.

Local entries are globally visible. So we can retrieve them from anywhere within the system.

There are three types of local entries in WSO2 ESB.
  1. In-lined Text Entry
  2. In-lined XML Entry
  3. Source URL Entry
In-lined Text Entry

In here we can add any text entry. For example if we want to add a name or number which has a high probability of changing time to time, we can add it as a in-lined text entry. And then we can retrieve this value inside the XML configuration and use it.

In-lined XML Entry

In here we can add XML entries.

Source URL Entry

This is for adding URLs as local entries. If that url contains a payload to be retrieved we can get that payload simply by retrieving the value of the local entry.

Retrieving local entries within the XML configuration

We can retrieve these values by writing a XPATH function like this. Assume the name of the local entry is "localEntry".

<property name="LocalEntryValue" expression="get-property('localEntry')"/>

Assume you have a XSLT function to be executed. In a case like this we can add a xsl:stylesheet in a local entry and call it from the source code (XML configuration of sequence/proxy or API). You can even pass parameters for this xslt function.

Here I have stated an example which calls a xslt function saved in an in-lined local entry. It is saved as "test.xsl". Key of this local entry can be specified wherever a registry key is expected in the configuration.

In the following example I have stated the way of calling the local entry and pass a property as a parameter to the xslt function.

 <xslt key="test.xsl">
        <property name="date_time" value="2016-05-24"/>
</xslt>



Thursday, August 4, 2016

Use of Templates in WSO2 ESB

When you have repeating code segments of ESB configurations/XMLs in your API or proxy service, you can add those code segments in a template defined in ESB. And also when you want to reuse a particular set of codes in different places you can include that part of XML configuration in a template and reuse. It will help to reduce the redundancy and your code will be more readable. A template is more similar to a class.


Basically there are two types of template patterns introduced by WSO2 ESB. They are sequence templates and endpoint templates. Here I will discuss about sequence template

A sequence template is a templated form of a sequence. Here I’m going to discuss how to call a template from a proxy service, pass parameters to template and to retrieve parameters from a template. And you can include the repeating code segments inside the template.

To create a template go to ‘Templates’ and click on ‘Add Sequence Template’. Then give a name to that.




Then click on ‘Add parameter’ to retrieve the parameters you pass when calling the template.



Here I have given two parameters (name and age). And then I will add a log mediator to log the parameter values retrieved from the template. For that you can simply click on ‘Add child’ and select the ‘Log’ mediator.



And give the properties you want to log like this.



Then click on ‘update’ then ‘Save & Close’. You can include the other relevant mediators of the XML configuration(repeating codes) here.

This is the final XML configuration of the template I created. In here we get the parameters passed from the proxy service which invokes this template and log them.

<?xml version="1.0" encoding="UTF-8"?>
<template xmlns="http://ws.apache.org/ns/synapse" name="testTemplate">
   <parameter name="name" />
   <parameter name="age" />
   <sequence>
      <log level="custom">
         <property xmlns:ns="http://org.apache.synapse/xsd" xmlns:ns2="http://org.apache.synapse/xsd" expression="get-property('name')" name="name" />
         <property xmlns:ns="http://org.apache.synapse/xsd" xmlns:ns2="http://org.apache.synapse/xsd" expression="get-property('age')" name="age" />
      </log>
   </sequence>
</template>
Then we will look into how to call this template from the proxy service and pass parameter

Create a custom proxy and give a name. Then click ‘Next’. Then select ‘Define Inline’. Then click on ‘Create’. After that click on ‘Add child’ then select ‘Call Template’.

There you can select the template you created in  ‘Target template’. Then you can give the values of parameters like this.
If the values of those parameters are as properties in the proxy service you can give the parameter values like this instead of directly giving the values.
Then update, save and close. And click ‘Next’ and “Finish’ to create the proxy.


Here I have added the XML configuration of the proxy service.

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="testTemplate" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
   <target>
      <inSequence>
         <property name="name" value="Sandra" scope="default" type="STRING" />
         <property name="age" value="25" scope="default" type="STRING" />
         <call-template target="testTemplate">
            <with-param xmlns:ns="http://org.apache.synapse/xsd" name="name" value="{get-property('name')}" />
            <with-param xmlns:ns="http://org.apache.synapse/xsd" name="age" value="{get-property('age')}" />
         </call-template>
      </inSequence>
   </target>
   <description />
</proxy>
Then you can run the proxy from ‘Try this Service’. Then you can see the output like this.








Sunday, July 31, 2016

Retrieve multiple rows from a database in WSO2 ESB using WSO2 DSS.

When you want to retrieve multiple rows from a database using WSO2 ESB, you will not be able to use the dblookup mediator as it only supports retrieving a single row. In a scenario like this we can use WSO2 DSS.

When you want to run two servers at the same time you have to set the offset in one server. Otherwise both servers will try to be up in the same port. You can do it by editing the carbon.xml file of the ESB or DSS. Go to [product-home]/repository/conf/carbon.xml. Then set the offset to ‘2’. (You can use any number you want). If you set the offset to 2,Server will be up in the port 9445.



Steps

Create a database in mysql server. And define a table including data you want. Here I have created a database named ‘company’ and a table named ‘employee’.



Configure DSS

Start the WSO2 DSS. Then go to the url of the serve and log into the server using username password. (username:admin password:admin).

Click on ‘Create’ under ‘Data Service’. You will be redirected to a page like the image shown below. You can simply give a Data Service Name and proceed. Here I have given the name as ‘Employee’.

When you click ‘Next’ you will see a screen like this. Here we have to add a new data source. Click on ‘Add New Datasource’. Give a datasource id and select the ‘Datasource Type’ as ‘RDBMS’ and ‘Database Engine’ as ‘MySQL’. Give the ‘Driver Class’ as ‘com.mysql.jdbc.Driver’. Give the ‘URL’ as ‘jdbc:mysql://localhost:3306/[database-name]’.You can give the name of the database you created. Then give the username and password of your database.

Save and click ‘Next’.

Click on ‘Add New Query’. Give a query id and select the Datasource you created. Write the sql query including the columns you want to retrieve from database. And click on ‘Generate Response’. It will automatically generate the Result(Output Mapping).


Then save the query and click ‘Next’.

Click on ‘Add New Operation’. Give an operation name and select the query Id of the query.



Save and click ‘Next’ and ‘Finish’. Now you have created the Data Service in DSS. When you refresh the page you will see the service you created.

Click on ‘Try this Service’ and it will redirect you to another page. You can click on ‘Send’ button to see the results you get after retrieving values from database.


If you know how to write the XML configuration you can directly edit the XML without doing the above mentioned steps using the UI. Here is the final XML you get after creating the data service.
<?xml version="1.0" encoding="UTF-8"?>
<data name="Employee" transports="http https local">
   <config enableOData="false" id="EmployeeDetails">
      <property name="driverClassName">com.mysql.jdbc.Driver</property>
      <property name="url">jdbc:mysql://localhost:3306/company</property>
      <property name="username">root</property>
   </config>
   <query id="getEmployees" useConfig="EmployeeDetails">
      <sql>SELECT name,emp_id,department from employee</sql>
      <result element="Entries" rowName="Entry">
         <element column="name" name="name" xsdType="string" />
         <element column="emp_id" name="emp_id" xsdType="string" />
         <element column="department" name="department" xsdType="string" />
      </result>
   </query>
   <operation name="retrieveEmployeeDetails">
      <call-query href="getEmployees" />
   </operation>
</data>

Now we are done with the configuration of DSS.

Configure ESB

Now we will move on to configure ESB. For you to fetch these data to ESB you have to  define an endpoint in ESB. Here I will define a HTTP endpoint. Go back again to DSS. Then click on the data service you created. Then copy the highlighted endpoint as shown in the image. (You have to copy the http endpoint. Not the https one).



Go to ESB to create the HTTP endpoint. Go to ‘Endpoints’ , ‘Add Endpoint’ and select ‘HTTP Endpoint’. Give a name. To define the URI template, paste the endpoint you copied from the DSS data service. And then add the operation name at the end of the URL like this.




Create a proxy service in ESB to retrieve data. You can create a proxy and write the XML configuration like this.

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="retrieve" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
   <target>
      <inSequence>
         <payloadFactory media-type="xml">
            <format>
               <dat:retrieveEmployeeDetails xmlns:dat="http://ws.wso2.org/dataservice" />
            </format>
            <args />
         </payloadFactory>
         <property name="Content-Type" value="application/xml" scope="transport" />
         <call>
            <endpoint key="retrieveEmpDetails" />
         </call>
         <log level="full" />
      </inSequence>
   </target>
   <description />
</proxy>

In this proxy service we define a payload factory mediator before calling the endpoint to give the reference to the namespace of DSS. Inside that payload we can define the namespace of the operation(retrieveEmployeeDetails) of the data service we created like this.

Since we get a XML payload from the data service we invoke in DSS we can set the Content-Type property value to application/xml and the scope to transport.This is optional.

Then we can call the endpoint we created in ESB like this, using the call mediator.
<call>
          <endpoint key="retrieveEmpDetails"/>
</call>

When you run this proxy service you can see the XML payload with the retrieved values from database like this.




Wednesday, July 27, 2016

[WSO2 ESB] Retrieving values from a payload excluding namespaces into a property.

Assume that we want to retrieve some elements from the payload excluding the namespaces.
We can do this in different ways.

1. If it is a payload defined by ourselves, we can define the payload with an empty namespace.

EX:

<Entries xmlns= "">
                 <Entry>
                    <name>Olivia</name>
                    <userId>1</userId>
        <age>25</age>
                 </Entry>
</Entries>

And we can write a XPATH expression to retrieve the required element into a property like this.

<property name="nameOfThePerson" expression="//Entries/Entry/name"/>

2. If it is a payload we are getting from an outside source, and it contains a namespace defined in the payload.

Here we have to define the namespace reference in our property mediator like this to retrieve only the value of the element without the namespace.

EX:

If the payload we are getting is like this,

<Entries xmlns= "http://wso2.samples.com">
                 <Entry>
                    <name>Olivia</name>
                    <userId>1</userId>
        <age>25</age>
                 </Entry>
</Entries>

And if we want to retrieve the value of the age element into a property.
This can be done in two ways,

i.) We can define the property with a reference to the namespace like this,

<property xmlns:ns="http://wso2.samples.com"
                  name="age"
                  expression="//ns:Entries/ns:Entry/ns:age"/>

ii.) This can be done without defining the namespace in property like this.

        <property name="age" expression="//*[local-name()='age']"/>

This expression will also retrieve the same age value. And here you don’t want to add the namespace reference. So it becomes much more simpler and clearer than the previous one.

Sample proxy service

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="removeNameSpaces" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
   <target>
      <inSequence>
         <payloadFactory media-type="xml">
            <format>
               <Entries xmlns="http://wso2.samples.com">
                  <Entry>
                     <name>Olivia</name>
                     <userId>1</userId>
                     <age>25</age>
                  </Entry>
               </Entries>
            </format>
            <args />
         </payloadFactory>
         <property xmlns:ns="http://wso2.samples.com" name="age" expression="//ns:Entries/ns:Entry/ns:age" />
         <property name="userId" expression="//*[local-name()='userId']" />
         <log level="custom">
            <property name="age" expression="get-property('age')" />
            <property name="userId" expression="get-property('userId')" />
         </log>
      </inSequence>
   </target>
   <description />
</proxy>
                               
Sample output