What is Adaptive Authentication ?? Adaptive authentication is an evolved form of multi factor authentication (MFA) where the authentication mechanism is decided depending on the the user’s risk profile and the behavior. You can understand this concept in detail by following “ ” . Adaptive Authentication: Why? What? How? supports script-based adaptive authentication since WSO2-IS 5.7.0 adding numerous advantages to users. WSO2 Identity Server Why you should select WSO2 IS for adaptive authentication? Ability to write complex authentication policies in a simple manner using embedded script editor in management console. It removes the barriers enforced by traditional UI tools to generate adaptive authentication flows. Shipping a set of well written templates on use cases such as role-based, user-age-based, tenant-based, user store based, IP-based, new device based, risk-based by default with the product. It makes the identity admin’s life comfortable and easier. Open and future-proof adaptive authentication platform which provides more value for less cost. Designed in such as a way to quickly integrate with risk engines and external systems. NOT only that !!! WSO2 IS introduced function library support for adaptive authentication to handle adaptive authentication scripts in a hassle free manner. Advantages of function library support for adaptive authentication The common Java script functions which are useful for adaptive authentication scripts can be stored as collections. Enhance the re-usability of common functions. Make adaptive authentication scripts more clear by importing function libraries and using their functions instead of writing everything in the same script. Make the users’ life easier by reducing the effort to modify and maintain scripts. Mechanism of importing libraries to adaptive authentication scripts is developer friendly as it uses a similar way of in NodeJS. require() How to use function libraries ? Use management console [ ] details Use REST API [ ] details Let’s use management console to add new function library. We are going to modify the “ ” template which already contains two java script functions inside the authentication script itself. ( and functions are the two common JS functions.). Let’s move them to one module and make the authentication script more cleaner. IP-Based convertIpToLong isCorporateIP [ ] Add Function Library details 1. Sign in to in to the Management Console. 2. On the menu, click → → . Main Manage Function Libraries Add 3. Fill in the , provide a brief Description (optional) and write the for the function library. Then click . Function Library Name Function Library Script Register 4. If the script doesn’t have any compilation errors, it will be sucessfully registerd. extension is added to the name you specified. You need to use that extension when importing a function library. (Can see later) .js .js ? How to write function library scripts There are three main methods: Add individual functions and export all individually. (Even though some functions are only invoked inside the same function library, those functions should be exported. Further, use as similar to usage inside function). Option 01: this.<function> this.convertIpToLong isCorporateIP convertIpToLong = { components = ip.split( ); (components) { ipAddr = , pow = ; ( i = ; i >= ; i -= ) { ipAddr += pow * (components[i]); pow *= ; } ipAddr; } { ; } }; isCorporateIP = { subnetLength = subnets.length; ( i = ; i < subnetLength; i++) { subnetComponents = subnets[i].split( ); minHost = .convertIpToLong(subnetComponents[ ]); ipAddr = .convertIpToLong(ip); mask = subnetComponents[ ]; (subnetComponents && minHost >= ) { numHosts = .pow( , - (mask)); ((ipAddr >= minHost) && (ipAddr <= minHost + numHosts - )) { ; } } } ; }; .exports.convertIpToLong = convertIpToLong; .exports.isCorporateIP = isCorporateIP; // Function to convert ip address string to long value var ( ) function ip var '.' if var 0 1 for var 3 0 1 parseInt 256 return else return -1 // Function to check if the ip address is within the given subnet var ( ) function ip, subnets var for var 0 var '/' var this 0 var this var 1 if 0 var Math 2 32 parseInt if 1 return true return false module module Create a a module which contains multiple functions and export the whole module itself. Option 02: networkUtils = { convertIpToLong : { components = ip.split( ); (components) { ipAddr = , pow = ; ( i = ; i >= ; i -= ) { ipAddr += pow * (components[i]); pow *= ; } ipAddr; } { ; } }, isCorporateIP : { subnetLength = subnets.length; ( i = ; i < subnetLength; i++) { subnetComponents = subnets[i].split( ); minHost = .convertIpToLong(subnetComponents[ ]); ipAddr = .convertIpToLong(ip); mask = subnetComponents[ ]; (subnetComponents && minHost >= ) { numHosts = .pow( , - (mask)); ((ipAddr >= minHost) && (ipAddr <= minHost + numHosts - )) { ; } } } ; } }; .exports = networkUtils; var // Function to convert ip address string to long value ( ) function ip var '.' if var 0 1 for var 3 0 1 parseInt 256 return else return -1 // Function to check if the ip address is within the given subnet ( ) function ip, subnets var for var 0 var '/' var this 0 var this var 1 if 0 var Math 2 32 parseInt if 1 return true return false module Define a module and add each function separately. Finally export the module. Option 03: networkUtils = { }; networkUtils.convertIpToLong = { components = ip.split( ); (components) { ipAddr = , pow = ; ( i = ; i >= ; i -= ) { ipAddr += pow * (components[i]); pow *= ; } ipAddr; } { ; } }; networkUtils.isCorporateIP = { subnetLength = subnets.length; ( i = ; i < subnetLength; i++) { subnetComponents = subnets[i].split( ); minHost = .convertIpToLong(subnetComponents[ ]); ipAddr = .convertIpToLong(ip); mask = subnetComponents[ ]; (subnetComponents && minHost >= ) { numHosts = .pow( , - (mask)); ((ipAddr >= minHost) && (ipAddr <= minHost + numHosts - )) { ; } } } ; }; .exports = networkUtils; var // Function to convert ip address string to long value ( ) function ip var '.' if var 0 1 for var 3 0 1 parseInt 256 return else return -1 // Function to check if the ip address is within the given subnet ( ) function ip, subnets var for var 0 var '/' var this 0 var this var 1 if 0 var Math 2 32 parseInt if 1 return true return false module : You must export the functions in a library in order to use them in any adaptive authentication script. IMPORTANT What’s Next !! Now you have a well prepared function library. It’s time to get use of it. 1. Follow all steps in to configure a service provider for adaptive authentication. this document 2. Instead of original IP-Based template, copy paste the following as the adaptive authentication script and try out the . sample scenario networkUtilsModule = ( ); corpNetwork = [ , ]; onLoginRequest = { executeStep( , { : { user = context.currentKnownSubject; loginIp = context.request.ip; Log.info( + user.username + + loginIp); (!networkUtilsModule.isCorporateIP(loginIp, corpNetwork)) { executeStep( ); } } }); }; var require 'networkUtils.js' // IP-Based from Template... // This script will step up authentication for any user who are trying to log in outside from the configured network // Configure the network ranges here var '192.168.1.0/24' '10.100.0.0/16' var ( ) function context 1 onSuccess ( ) function context var // Extracting the origin IP of the request var 'User: ' ' logged in from IP: ' // Checking if the IP is within the allowed range if 2 // End of IP-Based....... To import a function library, Add var <module_name> = require('<function library name>'); Eg: on top of the script/ before the usage of functions in the function library. var networkUtilsModule = require(‘networkUtils.js’); Use the functions in the loaded function library, E.g: networkUtilsModule.isCorporateIP(loginIp, corpNetwork) 3. Similarly you can import multiple function libraries into one adaptive authentication script and use them. When you compare the above script (which uses the imported library) and the original IP-Based template, you will agree with the “advantages of function library usage” which I pointed earlier. Nothing difficult right?? Try out this and enjoy your life !! NOTE: Please read on the to import function libraries to the adaptive authentication scripts. instructions Limitation: functionality is not supported inside function libraries. (i.e You won’t be able to import one function library into another function library) require() : Grab more knowledge [1] https://wso2.com/whitepapers/keep-calm-and-authenticate-why-adaptive-is-the-next-best-thing/ Previously published at https://medium.com/@anuradha.15/try-out-adaptive-authentication-with-function-libraries-in-wso2-is-35147aea14e7