Sunday, January 8, 2017

Logging in to a .NET application using the WSO2 Identity Server

OIDC client sample in .NET


  • Select Configuration (under Oauth/OpenID Connect Configuration)

  • Start the .NET application and fill the necessary details (eg: client id/ request uri etc), then it gets redirected to the IS authentication endpoint

(Note: Client key/secret can be found under Inbound Authentication and Configuration section of the created SP)

  • Authenticate via IS


  • Select Approve/Always Approve

  • After successfully authenticated, user gets redirected back to callback page with the oauth code. Then we need to fill the given information (eg: secret/grant type etc) and submit the form to retrieve the token details. It does a REST call to token endpoint and retrieve the token details. Since it does a server to server call we need to import the IS server certificate and export to Visual Studio Management Console to avoid SSL handshake exceptions.

  • Once the REST call is succeeded we could see the token details alone with the base64 decoded JWT (ID Token) details.



Tuesday, November 29, 2016

How to invoke a REST API Asynchronously


Dependencies:

<dependency>
   <groupId>org.apache.httpcomponents</groupId>
   <artifactId>httpclient</artifactId>
   <version>4.3.1</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpasyncclient</artifactId>
    <version>4.0</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpcore-nio</artifactId>
    <version>4.3</version>
</dependency>

Sample Code snippet:

private static void sendAsyncRequest(final HttpPost postRequest, 
FutureCallback futureCallback, CountDownLatch latch)
        throws IOException {
    CloseableHttpAsyncClient client;
    client = HttpAsyncClients.createDefault();
    client.start();
    client.execute(postRequest, futureCallback);
    try {
        latch.await();
    } catch (InterruptedException e) {
        log.error("Error occurred while calling end point - " + e);
    }
}






private void postRequest() throws IOException {
    final HttpPost postRequest = new HttpPost("www.google.com");
    final CountDownLatch latch = new CountDownLatch(1);
    FutureCallback<HttpResponse> futureCallback = 
new FutureCallback<HttpResponse>() {
        @Override public void completed(final HttpResponse response) {
            latch.countDown();
            if ((response.getStatusLine().getStatusCode() != 201)) {
                log.error("Error occurred while calling end point - " + response.getStatusLine().getStatusCode() +
                                  "; Error - " +
                                  response.getStatusLine().getReasonPhrase());
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("Success Request - " + postRequest.getURI().getSchemeSpecificPart());
                }
            }
        }

        @Override public void failed(final Exception ex) {
            latch.countDown();
            log.error("Error occurred while calling end point - " 
+ postRequest.getURI().getSchemeSpecificPart() +
                              "; Error - " + ex);
        }

        @Override public void cancelled() {
            latch.countDown();
            log.warn("Operation cancelled while calling end point - " +
                             postRequest.getURI().getSchemeSpecificPart());
        }
    };
    sendAsyncRequest(postRequest, futureCallback, latch);
}

Saturday, March 19, 2016

Writing SQL Queries support multiple RDBMS engines (using ANSI SQL standards)

In this post Im trying to discuss some best practices when writing SQL queries to support multiple RDBMS's. In many cases UPDATE, DELETE, INSERT operation syntaxes are standard but when it comes to SELECT operations we need to focus on writing generic queries to support multiple RDBMS engines.

  • Use COALESCE key word to handle null. 
eg:
SELECT COALESCE(CITY_NAME, 'Colombo')
FROM CITY
NVL() is for Oracle and ISNULL() is for RDBMS's like MS-SQL/MySql while COALESCE() is an ansi standard

  • Do not user hardcoded boolean result when using COALESCE 
eg:
SELECT COALESCE(IS_MARRIED, 'FALSE')
FROM EMPLOYEE
This query will not execute some RDBMS engines like MySql where boolean datatype is treated as a binary.  So to avoid this we need to pass the default value (FALSE) as a boolean parameter
eg: 
SELECT COALESCE(IS_MARRIED, ?)
FROM EMPLOYEE
boolean isMarried = false;
ps.setBoolean(1, isMarried);


  • Try to avoid String concatenation from SQL level. AFAIK there's no generic syntax to concatenate strings. (eg:  + sign is used in MS-SQL while || sign is used in Oracle to concatenate strings)
  • Do not use 'AS' key word for making table name alias's 
eg: 
SELECT EMP.*
FROM EMPLOYEE AS EMP
This syntax is not generic, instead use;
SELECT EMP.*
FROM EMPLOYEE EMP

  • Aggregate functions are generic in most RDBMS engines (eg: MIN, MAX, AVG, COUNT(*), COUNT)
  • Key words like UNION, UNION ALL, DISTINCT are generic.
  • Do not use ALL as a column/table alias
  • Do not use alias partially
eg:
SELECT * FROM (
SELECT EMP1.EMP_ID, EMP1.EMP_NAME
FROM EMPLOYEE1 EMP1
UNION ALL
SELECT EMP2.EMP_ID, EMP2.EMP_NAME
FROM EMPLOYEE2 EMP2)
ORDER BY EMP_ID
This query will execute in engines like H2 but it will fail in MySql. If you are using alias's, use it everywhere.
SELECT EMP_ALL.* FROM (
SELECT EMP1.EMP_ID, EMP1.EMP_NAME
FROM EMPLOYEE1 EMP1
UNION ALL
SELECT EMP2.EMP_ID, EMP2.EMP_NAME
FROM EMPLOYEE2 EMP2) EMP_ALL
ORDER BY EMP_ALL.EMP_ID
  • Regarding DDL statements, always keep the entity names equal or below 30 characters.







Monday, February 29, 2016

WSO2 App Manager - Using JWT to send application user details to Backend Application


JSON Web Token (JWT) is a means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is digitally signed using JSON Web Signature (JWS) and/or encrypted using JSON Web Encryption (JWE).


For more information regarding JWT configuration with WSO2 AppM please refer below articles.


How to Configure samples:


Here I'm trying to provide a sample .NET backend application which decode the JWT token and retrieve the Last name 

To test this, you need to build this application and host the binary in a IIS server. Then create a WebApp in WSO2 AppM and provide the relevant url as the backend url.  Also do not forget to add the 'lastname' as a claim mapping as explained in above articles.


Sample code to read header token values using ASP.NET (with C#.NET back end)

namespace Sample{
 public partial class _Default: System.Web.UI.Page {
  protected void Page_Load(object sender, EventArgs e) {
   try {
    if (!Page.IsPostBack) {
     //store the value of claim :http://wso2.org/claims/lastname
     String lastName = "";

     //check for X-JWT-Assertion parameter
     if (Request.Headers["X-JWT-Assertion"] != null) {
      reqHeader = Request.Headers["X-JWT-Assertion"].ToString();
      string[] stringSeperator = new string[] {
       "=."
      };
      //split the encoded string and send to decode
      string decodedHeader = base64Decode(reqHeader.Split(stringSeperator, StringSplitOptions.None)[1].ToString() + "=");
      decodedHeader = decodedHeader.Replace("\"", "'"); //format json string
      JObject obj = new JObject();
      obj = (JObject) JsonConvert.DeserializeObject(decodedHeader); //Decode Object

      if (obj["http://wso2.org/claims/lastname"] != null) {
       lastName = obj["http://wso2.org/claims/lastname"].ToString();
      }

     }
    }
   } catch (Exception ex) {
    //lblErr.Text = "Error: " + ex.Message;
   }

  }

  //base64 decodes the given encoded string (data :encoded string)
  public string base64Decode(string data) {
   try {
    System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding();
    System.Text.Decoder utf8Decode = encoder.GetDecoder();
    byte[] todecode_byte = Convert.FromBase64String(data);
    int charCount = utf8Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length);
    char[] decoded_char = new char[charCount];
    utf8Decode.GetChars(todecode_byte, 0, todecode_byte.Length, decoded_char, 0);
    string result = new String(decoded_char);
    return result;
   } catch (Exception e) {
    throw new Exception("Error in base64Decode" + e.Message);
   }
  }
 }
}


More samples: 



Sunday, February 28, 2016

WSO2 App Manager - How to Create a Web Application

WSO2 App Manager - Web Application Creation end user configuration guide


In this post I'm trying to discuss the configuration options available in creating a WebApp.

To create a Web Application you need to log into publisher with an user who has the "Internal/creator" (or "admin") Role.

URL: http://<IP_ADDRESS>:9763/publisher

Login to Publisher > Click on Web Applications >  Add New Web Application



Overview section





Overview Properties:
AuthorUsername of the user who publish the app
NameApplication name (for internal usage only)
Display NameApplication Display Name 
ContextURL Context
VersionVersion of the Application (eg: 1.0, 1.1, 2.0)
Make As Default VersionWhen creating a new Application this is always set as marked and later when you create another version of the same Application you can swap the default versions

(Please refer wso2-app-manager-multiple-versioning for more information)
TransportsTransport protocol (either HTTP or HTTPS)
Treat as a SiteIf you select this, the published App will be act as a Site. (WSO2 AppM supports 3 type of Application types. WebApps, Mobile Apps and Sites) 
Web App URLBack end actual URL of the Application (eg: http://wso2.com)
DescriptionDescription about the Application
ThumbnailYou can browse the image of the Thumbnail to be displayed
BannerYou can browse the image of the Banner to be displayed
TagsYou can define multiple tags against each application which will be useful when searching Apps by keywords (eg: HR, Educational, Engineering, etc)

Policies Section

Under Policies we have 2 main categories:
  • Global Policies : Global Policies are applied agains an Application
  • Resource Policies: Resource Policies are applied agains the selected resource patterns of an Application


Global Policies



Global Policy properties:
Allow Anonymous AccessMake the whole App anonymously accessible. In the Store, users will be able to access the app (all the resources  patterns inside the app) without login in.
Eg: We we mark http://wso2.com as anonymous, users will be able to access any page inside (eg: http://wso2.com/contact/ , http://wso2.com/partners/) anonymously

(Please refer wso2-app-manager-anonymous-app-support for more information)
Skip Creating Proxying WebAppThis will skip the gateway. It will allow users to directly access the back end actual URL without going through the gateway(proxy). So in the Store - overview page it will show the actual back end URL
Restrict VisibilityConfiguration of Role Based Visibility in WSO2 AppM. You can specify the Roles which are eligible to access the App. So in the Store only Users with the particular Roles (and of course the users with Admin Role) will only be able access/view the App

(Please refer wso2-app-manager-role-based for more information)
Enable Single LogoutYou can define a custom Single Sign Out URL
Publish StatisticsEnable publishing statistics to BAM
Subscription AvailabilityControls the subscription availability. WSO2 AppM allow users to subscribe to Apps in multiple tenants. Here you can control the subscription levels. 
There are 3 options available:
  • current_tenant : Only the users in current tenant will be eligible to subscribe
  • all_tenants : Users in all tenants will be eligible to subscribe
  • specific_tenants : Users in specified tenants will be eligible to subscribe


Resource Policies



Resource policies are applied agains selected resource patterns in an application. 
When you need to apply several restrictions to some particular resource in a app you this will be useful.

Eg:
You have http://wso2.com as your back end but you need to add a throttling policy to a certain page (lets say http://wso2.com/register/) to limit access, Resource policies will be needful.


WSO2 AppM supported Resource based Policy types:
  • Throttling : Controls/restrict the concurrent requests
  • Anonymous Access: Allow users to anonymously access the resource pattern(s)
  • Role based Restrictions: Grant access to users with selected Role(s)
  • XACML policies (Entitlement policies): You can define XACML based authorization policies and apply against resource pattern(s) 


There are two steps you need to follow:
  • Define a Policy Group with required policy combination
  • Apply the Policy Group against each Resource Pattern

When you are creating a new Application a default Policy Group with below default policy combinations are created by default. You can either change the properties or create new policy groups according to your requirement.

Default Policy Group settings:
  • Throttling : Unlimited
  • Anonymous Access: False
  • Role based Restrictions: None
  • XACML policies (Entitlement policies): None

To create a Policy Group:
Expand Policies > Resource Policies  and click on "Add new Resource Policy" button.



Resources based Policy properties:
Resource Policy NameName of the policy Group
DescriptionDescription about the policy group
Apply Throttling TierSelect a Throttling Tier from available Tiers (Unlimited/ Gold/ Silver/ Bronze)

Default concurrent access limits are:

  • Unlimited: Unlimited no of accesses
  • Gold: 20
  • Silver: 5
  • Bronze: 1

For the Anonymous users throttling tier will not be applied and it always be unlimited.

(Technical tip: You can customerize the tier setting as per your requirement by altering the tiers.xml file in /_system/governance/appmgt/applicationdata/ registry location)
Allow Anonymous AccessTrue/False
Select 'true'  to make the Resource pattern anonymously accessible

(Please refer wso2-app-manager-anonymous-app-support for more information)
Accessible User Roles Role based restriction for Resource patterns.
You can specify the Roles which are eligible to access the particular Resource Pattern. So in the Store only Users with the particular Roles (and of course the users with Admin Role) will only be able access/view the particular Resource Pattern

(Please refer wso2-app-manager-role-based for more information)
Entitlement PolicyYou can define a XACML Policy in the admin-dashboard and apply the policy here.


How to edit/delete policies in Policy Group?



Edit: Click on  icon to edit existing Policy Group details.  But the policy changes will be effective once the cache is reset.

Detele: Click on  icon to delete a Policy Group. It will only allow to delete the un assigned policy group(s) for any resource pattern.


How to assign a policy group to a particular resource pattern?



Under "Web Application Resources" section all the resource patterns will be listed in a grid view. 
And under "Resource policy" column you can choose the relevant policy group agains each resource pattern.



Web Application Resources Section

Navigate to "Web Application Resources" section. 


Here you can add multiple resource patterns and assign custom policies.


Web Application Resources properties:
URL PatternURL Pattern (Resource Pattern) is a sub domain or a page in side the actual endpoint of the Application.

Eg:
Actual End point of the App: http://wso2.com
URL Pattern1: register (refers http://wso2.com/register)
URL Pattern2: contact (refers http://wso2.com/contact)
HTTP VerbEither GET/POST/PUT/DELETE/OPTION

Resource Policy
Select the appropriate resource policy. By default, "Default" policy group is assigned to all patterns initially.

If you assign any policy group against /{context}/{version} /* it will be applicable for all the resources with the relevant HTTP Verb. 

Eg: 
URL Pattern:  /{context}/{version} /*
HTTP Verb: GET
Resource Policy: Anonymous-Group

In this case the Anonymous-Group policies will be applicable for all the GET operations (all underneath URL Patterns as well).

So another URL pattern like below will be override the permissions for mentioned resources.
URL Pattern:  /{context}/{version} /register
HTTP Verb: GET
Resource Policy: Default


How to add a new resource pattern? 
Type the URL Pattern, select the HTTP Verb and click on "Add Resource" button.
By default, the "Default" policy group will be assigned as Resource Policy and you can select the relevant Resource Policy from defined list.


Advanced Configuration Section



Claims

In this section you can add claims against the newly created application.

What is a Claim?
Here you can find details about what is a Claim, how to add new mappings and many more details.

A claim be use as a container to pass specific attributed to back end service via a JWT (https://docs.wso2.com/display/AM190/Passing+Enduser+Attributes+to+the+Backend+Using+JWT)


How to add Claims?

Select the required claim from the "Available Claims" drop down and click on "Add Claim" button.


OAuth2 Key Manager Configuration


OAuth2 Key manager configurations can be stored here.

What is it?
WSO2 AppM supports SAML SSO to authenticate an user. If your backend application uses internal OAuth API calls you can use this feature to use the same SAML token generated by WSO2 AppM gateway, and get an OAuth2 access token by calling the token endpoints used by these APIs. 

OAuth2 Key Manager Configuration properties:
API NameAlias for the API
API Consumer KeyConsumer Key of the OAuth API
API Consumer Secret
 Consumer Secret of the OAuth API
API Token Endpoint
URL of the token endpoint used by API



How to View the created WebApps and Sites

Once the WebApp/Site is Created successfully, it will be listed under Publisher listing page.
(Login to Publisher > Web Applications > All Web Applications)


WebApp/Site  Listing:


Edit an Application

To Edit the Apps you can simply navigate to app listing page and click on any app, do the changes and update.





Here you need to know that, you wont be able to change the app name,context and version.
If you need, you can change the display name. And if you need to change a version you can follow wso2-app-manager-multiple-versioning for more information.


Sunday, February 21, 2016

Using REGEX


Summary of Regular Expression Constructs

(Source: Oracle Website)

Characters
width="132"xThe character x
\\The backslash character
\0nThe character with octal value 0n (0 <= n <= 7)
\0nnThe character with octal value 0nn (0 <= n <= 7)
\0mnnThe character with octal value 0mnn (0 <= m <= 3, 0 <= n <= 7)
\xhhThe character with hexadecimal value 0xhh
\uhhhhThe character with hexadecimal value 0xhhhh
\x{h…h}The character with hexadecimal value 0xh…h (Character.MIN_CODE_POINT <= 0xh…h <= Character.MAX_CODE_POINT)
\tThe tab character (‘\u0009’)
\nThe newline (line feed) character (‘\u000A’)
\rThe carriage-return character (‘\u000D’)
\fThe form-feed character (‘\u000C’)
\aThe alert (bell) character (‘\u0007’)
\eThe escape character (‘\u001B’)
\cxThe control character corresponding to x

Character classes
[abc]a, b, or c (simple class)
[^abc]Any character except a, b, or c (negation)
[a-zA-Z]a through z or A through Z, inclusive (range)
[a-d[m-p]]a through d, or m through p: [a-dm-p] (union)
[a-z&&[def]]d, e, or f (intersection)
[a-z&&[^bc]]a through z, except for b and c: [ad-z] (subtraction)
[a-z&&[^m-p]]a through z, and not m through p: [a-lq-z](subtraction)

Predefined character classes
.Any character (may or may not match line terminators)
\dA digit: [0-9]
\DA non-digit: [^0-9]
\sA whitespace character: [ \t\n\x0B\f\r]
\SA non-whitespace character: [^\s]
\wA word character: [a-zA-Z_0-9]
\WA non-word character: [^\w]

Boundary matchers
^The beginning of a line
$The end of a line
\bA word boundary
\BA non-word boundary
\AThe beginning of the input
\GThe end of the previous match
\ZThe end of the input but for the final terminator, if any
\zThe end of the input


Example:

 import java.util.regex.Matcher;  
 import java.util.regex.Pattern;  
 public class RegexMatchesSample  
 {  
      private static String pattern = "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";  
      private static Pattern customPattern = Pattern.compile(pattern);  
      public static void main( String args[] ){  
           String validEmail1 = "testemail@domain.com";  
           String validEmail2 = "test.email@domain.com";  
           String invalidEmail1 = "....@domain.com";  
           String invalidEmail2 = ".$$%%@domain.com";  
           System.out.println("Is Email ID : '" + validEmail1+ "' valid? - "+validateEmailID(validEmail1));  
           System.out.println("Is Email ID : '" + validEmail2+ "' valid? - "+validateEmailID(validEmail2));  
           System.out.println("Is Email ID : '" + invalidEmail1+ "' valid? - "+validateEmailID(invalidEmail1));  
           System.out.println("Is Email ID : '" + invalidEmail2+ "' valid? - "+validateEmailID(invalidEmail2));  
      }  
      public static boolean validateEmailID(String emailID) {  
           Matcher mtch = customPattern.matcher(emailID);  
           if(mtch.matches()){  
                return true;  
           }  
           return false;  
      }        
 }  

Result:
Is Email ID : 'testemail@domain.com' valid? - true
Is Email ID : 'test.email@domain.com' valid? - true
Is Email ID : '....@domain.com? - false
Is Email ID : '.$$%%@domain.com' valid? - false