Discover our knowledge. Read our blogs!

Learn more

We build all our solutions with WSO2 and we are proud that we are WSO2 Premier Certified Integration Partner and Value-Added Reseller.

Learn more

Conditional Authentication with WSO2 Identity Server

9 min read

Login instagram - authenticationAs today’s information systems are going through a rapid wave of security hardening, Multi-Factor Authentication is coming into the spotlight to ensure the identity of a user in more context-aware mechanisms. The ability to adapt and switch based on multiple different scenarios a user may access your system, is imperative in this context.

For example, let's say your system handles user login through 3 factors — Basic credentials, face detection and a One-time-Password sent to the email. Now, if user A is accessing your system from the Company intranet, you may want to make the login process easier by skipping the One-time-Password. This pattern for the Administrator to conditionally enable/ disable steps in the login flow is formally defined as “Conditional Authentication”, and WSO2 Identity Server has come up with a neat feature to facilitate this.

I hope the following walkthrough will help you grasp this concept and use it wisely!

Background of the Sample

To demonstrate this feature, I will pick a scenario where a system has 2 authentication steps; Basic credentials and Email based One-Time-Password authentication. The example will be based on the case of the user trying to login to the system from public internet, or from the company intranet, so that, if the user is within the company intranet, this sample will skip the Email OTP authentication step. The condition will be based on the authentication request’s source IP address, inferred from the “x-forwarded-for” header.

Pre-requisites

  • WSO2 Identity Server 5.6.0
  • Nginx server (To simulate the x-forwarded-for header)
  • Apache tomcat 9.x
  • Google account with app permission: (You will need to create a test google account)
  • Sample web application with SSO enabled

Sample Web application

You can download the war file I used here, or build it from the source by cloning from this repo.

Copy the built war file from above path to your tomcat webapps directory and make sure that it is deployed successfully.

** Going along WSO2 guidelines, I have used “localhost.com” in the webapp. Therefore, we need to add a mapping to it at the /etc/hosts file (in case of Linux) :

`127.0.0.1 localhost.com`

Identity server configuration

Email OTP configuration

We can follow the official WSO2 documentation to configure this. For reference, I have listed the changes to "repository/conf" directory here.

However, different to the document, we are using the newer SAML2 SSO sample web application. The Identity provider and service provider configuration from my setup is below:

Add new Identity Provider - conditional authentication with WSO2

Identity Provider required for federating EmailOTP to Google

Service providers - conditional authentication with WSO2

Service Provider needed for the web application

Register new service provider-conditional authentication with WSO2

Service Provider — SAML SSO configuration

SAML SSO configuration-conditional authentication with WSO2

Service Provider — Local and Inbound Authentication Configuration

Now we can try out the login flow with URL “http://localhost.com:8080/saml2-web-app-dispatch.com". You will see the below sequence:

PickUp WSO2-Conditional Authentication with WSO2

Sign in

 

Email verification - conditional authentication with WSO2

PickUp Dispatch

*** Make sure to update the admin user's email address to a valid email address so that you can retrieve the OTP code from the email.

Making things conditional

Custom Claim to hold the trusted values

We are trying to skip the OTP authentication if the user’s IP address is a trusted one. So, we need a way to store each user’s trusted IP address in their profile for comparison with incoming requests. Best way to do this is by using a custom claim.

1. Navigate to “Claims” -> “Add” -> “Add local claim” and create a claim with following attributes:

update Local Claim - conditional authentication with wso2

2. Since we have enabled the claim as a default attribute on user profile, you can update the test user’s profile with the trusted IP address value:

Update Profile; admin - conditional authentication with wso2

Adding the authentication script

  1. Restart the Identity server as: “sh wso2server.sh -DenableConditionalAuthenticationFeature”
  2. Once started you will be able to see below extra section below the authentication steps in the “Local and Outbound Authentication Configuration” -> “advanced” section in the service provider:

Advanced authentication configuration - Conditional authentication with WSO2

  1. Check the box “Enable script based conditional authentication” and paste the following block into the text area :

Enable script based conditional authentication

  1. Click update on the configuration as well as the service provider page.

All ready except...

The “x-forwarded-for” header is not a default header in HTTP requests. It is only added if the request has been routed through a proxy / load balancer, meaning that the WSO2 Identity server has to be behind a proxy for us to capture the header from the authentication request.

This is common practice in production environments. Therefore, to simulate the header, we need to front the Identity server with a load balancer, which is in our case, Nginx.

  1. Install Nginx.
  2. Create a public and private key to be used for Nginx routing:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout <KEY_FILE_PATH> -out <CERTIFICATE_PATH>

  1. Add the following block to nginx.conf file just before the line “include servers/*;”

Nginx.conf file - conditional authentication with WSO2

  1. Restart the Nginx server.
  2. What we are essentially doing here is let Nginx listen on the default WSO2 port while the traffic can be routed to an Identity server with port offset. So, you will also need to increase the port offset = 2 in the IS_HOME/repository/conf/carbon.xml and restart the Identity server.

Ready ... Set ... Go!!

Now we are ready to try out conditional authentication based on the request IP address!

  1. Update the “Known IP Address” value of “admin” user to be “10.10.3.12” from the WSO2 management console.
  2. Login to the app at “http://localhost.com:8080/saml2-web-app-dispatch.com". You will notice that the login flow includes both basic authentication and the OTP code.
  3. Update the “Known IP Address” value of “admin” user to be “127.0.0.1” from the WSO2 management console.
  4. Login to the app at “http://localhost.com:8080/saml2-web-app-dispatch.com". You will notice that the login flow ends with just basic authentication.

Finishing thoughts

This is a very powerful feature coming with the latest WSO2 Identity server, and we can use various other information from the request headers, user claims, or even user roles to customize the authentication flow at run time.

Happy authenticating!

Care to share?
   
Picture of Hasitha de Silva
Published July 26, 2018

Hasitha de Silva

Hasitha is an Integration Consultant with more than 5 years experience in middleware integration and development, and is passionate about the cutting-edge developments in digital transformation. He has been a part of several integration projects and enjoys getting technical to find the right solutions.

Responses

Stay up to date with the latest articles