Wednesday, December 26, 2018

Useful LDAP Search Queries

This article provides some mostly used LDAP queries, which were commonly used in Integration projects.

H - ldap URI eg: ldap://192.168.1.1/
D - Distinguished Name of the Ad User
b - Search base
s sub -  {base|one|sub|children}
x - Use simple authentication instead of SASL
w - Password

 1) Retrieving Particular User Information based on CN  
   
 ldapsearch -LLL -H <LDAP-URI> -D '<LDAP-AD-USER>' -b '<LDAP-SEARCH-BASE>' -s sub -x "(&(objectClass=User)(CN=Test User \282001\29))" "cn objectGUID" -w <PASSWORD>  
   
 Note: Here \28 is for ( and \29 is for ), otherwise there will be a exception  
   
 2) Retrieving Particular User Information based on DN  
   
 ldapsearch -LLL -H <LDAP-URI> -D '<LDAP-AD-USER>' -b '<LDAP-SEARCH-BASE>' -s sub -x "(&(objectClass=User)(distinguishedname=<DN-USER>))" "cn" "objectGUID" -w <PASSWORD>  
   
 3) Retrieving Only the Active Users  
   
 Need to use this filter (!(userAccountControl:1.2.840.113556.1.4.803:=2)) to retrieve only the active users.  
   
 ldapsearch -LLL -H <LDAP-URI> -D '<LDAP-AD-USER>' -b '<LDAP-SEARCH-BASE>' -s sub -x "(&(objectClass=User)(distinguishedname=<DN-USER>)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))" "cn" "objectGUID" -w <PASSWORD>  
   
 4) Retrieve Groups of a particular User  
   
 ldapsearch -LLL -H <LDAP-URI> -D '<LDAP-AD-USER>' -b '<LDAP-SEARCH-BASE>' -s sub -x "(&(objectClass=Group)(member=<DN-USER>))" "cn" "objectGUID" -w <PASSWORD>  
   
 Note: Here for member=<Need to provide distinguishedName>  
   
 5) Retrieve Users of a particular Group  
   
 ldapsearch -LLL -H <LDAP-URI> -D '<LDAP-AD-USER>' -b '<LDAP-SEARCH-BASE>' -s sub -x "(&(objectClass=User)(memberOf=<DN-GROUP>))" "cn" "objectGUID" -w <PASSWORD>  
   
 6) Retrieving Users of a Group with pagination  
   
 ldapsearch -LLL -H <LDAP-URI> -D '<LDAP-AD-USER>' -b '<LDAP-SEARCH-BASE>' -s sub -x "(&(objectClass=Group)(CN=LoopTest2Group))" "cn" "objectGUID" "member;range=0-1" -w <PASSWORD>  
   

Sunday, November 11, 2018

Retrieving subset of xml using xslt mediator in WSO2 ESB 5.0.0

This article explain a solution to a scenario, where our back end service is not supporting a pagination and responds with a large xml and our client expects an API which need to support pagination.

The flow diagram below summarizes the task we are going to achieve.

The API I have created for this sample as below:

<api xmlns="http://ws.apache.org/ns/synapse" name="PaginationAPI" context="/listStudents">
   <resource methods="GET" uri-template="/getPaginatedStudentsList?start={start}&amp;count={count}" protocol="http">
      <inSequence>
         <log level="custom">
            <property name="STATUS" value="PaginationAPI Invoked..."/>
            <property name="start" expression="$ctx:query.param.start"/>
            <property name="count" expression="$ctx:query.param.count"/>
         </log>
         <script language="js">var count = parseInt(mc.getProperty('query.param.count'));                var start = parseInt(mc.getProperty('query.param.start'));        var startIndex = parseInt(start);       var endIndex = parseInt(start) + parseInt(count) + 1;         mc.setProperty('startIndex', startIndex);        mc.setProperty('endIndex', endIndex);</script>
         <call>
            <endpoint>
               <http method="GET" uri-template="http://www.mocky.io/v2/5be818f7300000750058c312"/>
            </endpoint>
         </call>
         <log level="full" description="before xslt transformation"/>
         <xslt key="gov:/pagination-test.xslt">
            <property name="startIndex" expression="$ctx:startIndex"/>
            <property name="endIndex" expression="$ctx:endIndex"/>
         </xslt>
         <respond/>
      </inSequence>
      <outSequence/>
      <faultSequence/>
   </resource>
</api>
                        

The back end service has been created in mocky.io and the sample data response from it will be as below:

<soapenv:Envelope
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
 <soapenv:Header/>
 <soapenv:Body>
  <students>
   <school>St.Michael's College, Batticaloa</school>
   <address>Batticaloa, Srilanka</address>
   <student>
    <recno>1</recno>
    <name>NTest1</name>
    <surname>STest1</surname>
    <address>ATest1</address>
    <age>27</age>
   </student>
   <student>
    <recno>2</recno>
    <name>NTest1</name>
    <surname>STest1</surname>
    <address>ATest1
   </address>
    <age>27</age>
   </student>
   <student>
    <recno>3</recno>
    <name>NTest1</name>
    <surname>STest1</surname>
    <address>ATest1</address>
    <age>27</age>
   </student>
   <student>
    <recno>4</recno>
    <name>NTest1</name>
    <surname>STest1</surname>
    <address>ATest1</address>
    <age>27</age>
   </student>
   <student>
    <recno>5</recno>
    <name>NTest1</name>
    <surname>STest1</surname>
    <address>ATest1</address>
    <age>27</age>
   </student>
   <student>
    <recno>6</recno>
    <name>NTest1</name>
    <surname>STest1</surname>
    <address>ATest1</address>
    <age>27</age>
   </student>
   <student>
    <recno>7</recno>
    <name>NTest1</name>
    <surname>STest1</surname>
    <address>ATest1</address>
    <age>27</age>
   </student>
   <student>
    <recno>8</recno>
    <name>NTest1</name>
    <surname>STest1</surname>
    <address>ATest1</address>
    <age>27</age>
   </student>
   <student>
    <recno>9</recno>
    <name>NTest1</name>
    <surname>STest1</surname>
    <address>ATest1</address>
    <age>27</age>
   </student>
   <student>
    <recno>10</recno>
    <name>NTest1</name>
    <surname>STest1</surname>
    <address>ATest1</address>
    <age>27</age>
   </student>
   <student>
    <recno>11</recno>
    <name>NTest1</name>
    <surname>STest1</surname>
    <address>ATest1</address>
    <age>27</age>
   </student>
   <student>
    <recno>12</recno>
    <name>NTest1</name>
    <surname>STest1</surname>
    <address>ATest1</address>
    <age>27</age>
   </student>
  </students>
 </soapenv:Body>
</soapenv:Envelope>

Then the XSLT will be as below:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
 <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
 <xsl:param name="startIndex"></xsl:param>
 <xsl:param name="endIndex"></xsl:param>
 <xsl:template match="/">
  <students>
   <xsl:apply-templates select="//students/student[position() > $startIndex and position() &lt; $endIndex]"/>
  </students>
 </xsl:template>
 <xsl:template match="//students/student[position() > $startIndex and position() &lt; $endIndex]">
  <xsl:copy-of select="."/>
 </xsl:template>
</xsl:stylesheet>

Below are the test results:
1) When calling the API with URL: http://172.17.0.1:8280/listStudents/getPaginatedStudentsList?start=0&count=20
<students>
    <student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <recno>1</recno>
        <name>NTest1</name>
        <surname>STest1</surname>
        <address>ATest1</address>
        <age>27</age>
    </student>
    <student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <recno>2</recno>
        <name>NTest1</name>
        <surname>STest1</surname>
        <address>ATest1
   </address>
        <age>27</age>
    </student>
    <student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <recno>3</recno>
        <name>NTest1</name>
        <surname>STest1</surname>
        <address>ATest1</address>
        <age>27</age>
    </student>
    <student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <recno>4</recno>
        <name>NTest1</name>
        <surname>STest1</surname>
        <address>ATest1</address>
        <age>27</age>
    </student>
    <student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <recno>5</recno>
        <name>NTest1</name>
        <surname>STest1</surname>
        <address>ATest1</address>
        <age>27</age>
    </student>
    <student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <recno>6</recno>
        <name>NTest1</name>
        <surname>STest1</surname>
        <address>ATest1</address>
        <age>27</age>
    </student>
    <student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <recno>7</recno>
        <name>NTest1</name>
        <surname>STest1</surname>
        <address>ATest1</address>
        <age>27</age>
    </student>
    <student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <recno>8</recno>
        <name>NTest1</name>
        <surname>STest1</surname>
        <address>ATest1</address>
        <age>27</age>
    </student>
    <student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <recno>9</recno>
        <name>NTest1</name>
        <surname>STest1</surname>
        <address>ATest1</address>
        <age>27</age>
    </student>
    <student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <recno>10</recno>
        <name>NTest1</name>
        <surname>STest1</surname>
        <address>ATest1</address>
        <age>27</age>
    </student>
    <student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <recno>11</recno>
        <name>NTest1</name>
        <surname>STest1</surname>
        <address>ATest1</address>
        <age>27</age>
    </student>
    <student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <recno>12</recno>
        <name>NTest1</name>
        <surname>STest1</surname>
        <address>ATest1</address>
        <age>27</age>
    </student>
</students>

2) When calling the API with URL: http://172.17.0.1:8280/listStudents/getPaginatedStudentsList?start=5&count=3
<students>
    <student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <recno>6</recno>
        <name>NTest1</name>
        <surname>STest1</surname>
        <address>ATest1</address>
        <age>27</age>
    </student>
    <student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <recno>7</recno>
        <name>NTest1</name>
        <surname>STest1</surname>
        <address>ATest1</address>
        <age>27</age>
    </student>
    <student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <recno>8</recno>
        <name>NTest1</name>
        <surname>STest1</surname>
        <address>ATest1</address>
        <age>27</age>
    </student>
</students>

That's it... and hope this helps someone implementing a pagination scenario.

Saturday, September 29, 2018

PART-1 : How OAuth 2.0 works and usage of it in WSO2 ESB and WSO2 APIM

OAuth 2.0 is an authorization framework, which provides limited access to a particular service. For example consider that i need to call service and get some information, and the service provider wants to give me access only to a particular period to retrieve the data, in this kind of situation oauth2.0 provides a mechanism to access the service without providing any user related credentials to the service temporarily.

Note: Main reference for this article is the https://tools.ietf.org/html/rfc6749?

Contents Included
1) Why OAuth 2.0
2) How OAuth 2.0 Works and Selecting the Authorization Grant
3) Usage in WSO2 APIM 2.1.0
4) Usage in WSO2 ESB 5.0.0

1) Why OAuth 2.0

Below figure illustrates how we normally used to access a service from our client application. In here you can see that we need to pass the services credentials to access the service. This will be an overhead because in that case we need to store the password and it may cause into security concerns and also if we want to revoke the access for the client then whole service password need to be changed.

Due to above mentioned disadvantages there was need for a protocol to handle the service invocation in a easier and secure way, that solution was OAuth 2.0.

2) How OAuth 2.0 Works

The basic request response flow in a OAuth 2.0 communication happens as below:

As mentioned in the above diagram the Authorization Grant call can be made in four types. We will look into each of them to get understand on the format of each calls.

Below is the Decision Tree which help us to identify which Grant Type to select when we are designing. The data has been extracted with the help of https://auth0.com/docs/api-auth/which-oauth-flow-to-use

3) Usage in WSO2 APIM 2.1.0

Now we will move to the usage of this in WSO2 APIM 2.1.0. OOB WSO2 provides a Token API which helps us to generate tokens and get use of the above grant types supported by OAuth 2.0. WSO2 APIM 2.1.0 Token API supports below Grant Types.

  • Authorization Code Grant
  • NTLM Grant
  • Password Grant
  • SAML Extension Grant
  • Client Credentials Grant
  • Implicit Grant
  • Kerberos OAuth2 Grant
  • Refresh Token Grant
Authorization Code Grant

This is a type of grant we can use in a scenario where we have web application and it need to get permission to access a resource. Below flow diagram explains the implementation I'm going to take as use case.

In this grant we need to give two calls to retrieve the token.
1) To retrieve the Authorization Code
2) To Retrieve the Access Token


To continue on this, first we will create a API and a Application in APIM. Follow the below screen shots to achieve this.








Now we have created the API. The next is to create an Application and subscribe the API to the Application. To achieve that log into store and below the below screens.










Now we have successfully configured and created the API. Now we need to create a web application to call and get the Authorization Code.

Below is a sample PHP Code to make the Authorization Code Request.


<?php

define("CALLBACK_URL", "http://localhost:80/ouath_call.php");
define("AUTH_URL", "https://localhost:8243/authorize");
define("CLIENT_ID", "gcKoevfZ4_ocYzvyZzBrkma7wpIa");
define("CLIENT_SECRET", "y1_yIcfxw6uaiDpJ2Mx1M1zfukca");
define("SCOPE", "PRODUCTION");

echo "Calling the Authorization Server to get the Authorization Code...";

$url = AUTH_URL."?"
   ."response_type=code"
   ."&client_id=". urlencode(CLIENT_ID)
   ."&scope=". urlencode(SCOPE)
   ."&redirect_uri=". urlencode(CALLBACK_URL)
;

echo "Authorization Request: " . $url;

header("Location: " . $url);

?>

Go to http://localhost:80/ouath_call.php, once you done that you will see the below page get routed.



To Make the token request use the below PHP code segment. Here the AUTH_CODE is extracted from the response of the previous call which generate the Authorization Code.

<?php

define("CALLBACK_URL", "http://localhost/ouath_call.php");
define("AUTH_URL", "https://localhost:8243/authorize");
define("CLIENT_ID", "gcKoevfZ4_ocYzvyZzBrkma7wpIa");
define("CLIENT_SECRET", "y1_yIcfxw6uaiDpJ2Mx1M1zfukca");
define("SCOPE", "PRODUCTION");
define("TOKEN_URL", "https://localhost:8243/oauth2/token");
define("AUTH_CODE", "d1a687a2-0c97-31a5-a628-7ffad6b75009");

echo "Calling the Token API to get the Access Code...<br/><br/>";

$authorization = base64_encode(CLIENT_ID . ":" . CLIENT_SECRET);
$header = array("Authorization: Basic {$authorization}","Content-Type: application/x-www-form-urlencoded");
$content = "grant_type=authorization_code&code=".AUTH_CODE."&redirect_uri=".CALLBACK_URL;
$token_url = "https://localhost:8243/token" ;


$curl = curl_init();
curl_setopt_array($curl, array(
        CURLOPT_URL => $token_url,
        CURLOPT_HTTPHEADER => $header,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => $content
));
$response = curl_exec($curl);
curl_close($curl);

echo "Response" . $response;
?>


Once we make the call, we will get the below response with the Access Token.

Hope Authorization Grant explanation is useful and will continue the other contents in my next blog.

Sunday, August 12, 2018

Message Flows in WSO2 APIM 2.1.0

This article explains how the message flow happens between the main WSO2 APIM 2.1.0 components. WSO2 API Manager includes five main components as the Publisher, Store, Gateway, Traffic Manager and Key Manager. Mainly there are three message flows in WSO2 APIM:

Note: In this article I'm not going to cover the Traffic Manager, it will be covered with details in my next blog.

1) API providers publish the APIs
2) Consumers subscribe to the APIs
3) Consumers of the service invoke the APIs

1) API providers publish the APIs
2) Consumers subscribe to the APIs
3) Consumers of the service invoke the APIs