Introduction: This document describes that how to maintain or allow multiple IP addresses/ IP address ranges in SAP API Management using KVM and Java Script policy.
Benefits to go with this approach
Here i am going to use the same API proxy which i have used in my earlier blog
Before going further, let me create one KVM called “AllowedIPs” and put IP addresses of one consumer where key is consumer name and value is multiple IP addresses or multiple IP address ranges or both
IP addresses or IP address ranges will be delimited by “,” and start and end IP address will be separated by “-” for IP address ranges.
Example : let’s take two IP addresses and one IP address range
123.12.12.11
123.11.11.10
134.12.12.01-134.12.12.15
So it will be entered in the value with format:- 123.12.12.11,123.11.11.10,134.12.12.01-134.12.12.15
Let me explain you with the help of below picture that what exactly i am going to do here.
In the above picture,
Let’s open the policy editor
2. “VAPIK” is a verify API key policy which will verify API key from the incoming request header and if key is valid then set the consumer name in “verifyapikey.VAPIK.DisplayName” property.
3. “GetAllowedIPs” is a KVM Operation policy, which will read AllowedIPs KVM with “verifyapikey.VAPIK.DisplayName” as key and after getting the value of that KVM key, it will assign that value to variable “var.AllowedIPs“.
4. “VerifyIP” is a java script policy, which is referring java script “VerifyIP.js“, VerifyIP java script will take request IP address from “request.header.X-Forwarded-For” and try to find it in AllowedIPs, if IP address is available in AllowedIPs then property “javascript.VerifyIP.failed” will set with false else with true.
VerifyIP.js
Code VerifyIP.js
function isIPInRange(ip, startRange, endRange) { // Convert IP addresses to numeric representation function ipToNumber(ip) { return ip.split('.').reduce((acc, octet, index, arr) => acc + parseInt(octet) * Math.pow(256, arr.length - index - 1), 0); } const ipNumber = ipToNumber(ip); const startRangeNumber = ipToNumber(startRange); const endRangeNumber = ipToNumber(endRange); return ipNumber >= startRangeNumber && ipNumber <= endRangeNumber; } var ipAddressKVM = context.getVariable("var.AllowedIPs"); const ipAddress = ipAddressKVM.split(','); const reqIPaddress=context.getVariable("request.header.X-Forwarded-For"); var exist =ipAddressKVM.includes(reqIPaddress); if (!exist) { for(i=0;i<ipAddress.length; i++) { if (ipAddress[i].includes("-")) exist = isIPInRange(reqIPaddress, ipAddress[i].split('-')[0], ipAddress[i].split('-')[1]); } } if (!exist) throw "Invalid IP";
5. “RFInvalidIP” is a raise fault policy which will execute if “javascript.VerifyIP.failed” is equal to true which means Java script policy is failed due to invalid IP.
In condition string “javascript.VerifyIP.failed equals true”
Write any custom message in payload like “Invalid IP address”.
6. Update policy, save proxy changes and deploy it.
Let’s do some positive and negative testing.
Positive testing: Getting API response because request IP address is configured in KVM.
Negative testing: Raise fault response is coming because request IP address is not configured in KVM.
Conclusion: This document explained that how to use KVM policy, How we can configure multiple IP address ranges and how to set dynamic key in KVM read operation.