Since 8.0.0.3 ISAM for Mobile has had the ability to call a Javascript Policy Information Point (PIP) during context based access (CBA, formerly risk based access – RBA) decisions for attribute enrichment. This capability is very flexible and can be used for many different purposes. Some examples include:
- Manipulating and extracting attributes from request headers.
This is performed by the out of the box PIP’s including the Trusteer PIP and the Worklight PIP. - Manipulating the data type of attributes.
An example is shown below, converting an attribute from a String to a Integer. - Calling an information service.
The Javascript framework has a number of functions available for both onbox and off box (internal and external) lookups. - Even just adding a custom value into your CBA context.
In this post, I’ll show an example using a JavaScript PIP to extract a String value from the ISAM credential, convert it to a Integer and then use it in an CBA policy protecting a resource.
IBM’s documentation for v8.0.1.0 can be found here.
Environment prerequisites
In following this example, I’ve already configured the following:
- ISAM for Web and ISAM for Mobile have already been fully configured.
- A junction has been created to a protected resource.
- The custom attribute SecurityLevel is added to the ISAM credential upon authentication.
(I’m using an extended attribute added via an EAI, but this could also be performed via loading a custom LDAP attribute.)
Custom Attribute definition
In order to write a policy with an attribute that is not defined from a default installation, it is necessary to define a custom attribute.
A new attribute can be easily defined under Secure Mobile Settings -> Access Control -> Attributes.
Name: Security Level
Identifier: urn:demo:securitylevel
Issuer: TagValuePIP
Category: Subject
Data Type: Integer
Matcher: exact_match
Type: Policy
Since this attribute is defined by the custom JavaScript PIP, the important values are the Identifier, which we specify in the JavaScript code, the Issuer which labels where the attribute is sourced, the category which tells CBA where the attribute will be stored in the XACML definition, and the data type which allows us to do integer/mathematical comparisons in our CBA policy.
Note: If you don’t select an attribute Type of Policy, you cannot see or use the attribute when writing a new policy.
Context Based Access Policy
The simple CBA policy I will use to demonstrate the use of a PIP is as follows:
The policy is a simple one, it will only permit access if the Security Level attribute is greater than or equal to 2.
Where possible I like to write my policies with the Precedence of First, this tends to make the policies easier to read with an If, Then, Else methodology.
Define your JavaScript PIP
In order to define a JavaScript PIP, it is necessary to implement two functions to meet the PIP Interface:
- function hasAttribute (requestedAttribute, category)
This function will return true if the PIP is capable of servicing the request. - function getAttributes (context, requestedAttribute, category)
This function will add the requested attribute to the context.
This sample requires we import a few libraries so that they are available in our JavaScript.
/** * Import packages necessary for the script to execute. */ importPackage(com.tivoli.am.rba.extensions); importClass(Packages.com.tivoli.am.rba.attributes.AttributeIdentifier);
JavaScript is used in a number of places on the appliance, and each appliance ships with the relevant and most up to date Java Documentation for it in the appliance Manage System Settings -> File Downloads section.
The most common way that the first mandatory function is implemented is to look at the requestedAttribute Issuer and match that against the defined PIP. In order to be dynamic, its possible to use the global variable instanceName of the PIP as the Issuer.
/** * This function will return true if an attribute's issuer matches the * instanceName of this PIP */ function hasAttribute (requestedAttribute, category) { // Dynamically set the issuerId that that this PIP services to the name // of the PIP. (Note this could be hardcoded). var issuerId = instanceName; // If Issuer matches, this PIP can service the request if (issuerId.equals(requestedAttribute.getIssuer())) { return true; } // This PIP can't service this request return false; }
The getAttributes function will fire when the hasAttributes function returns true. The getAttributes function is where the logic of attribute enrichment occurs. In this example getAttributes will extract the String attributes supplied in the ISAM credential, and convert them to an integer and add the attributes back into the context.
/** * This function extracts the value from the ISAM context, * converts it to an int and adds it back into the context */ function getAttributes (context, requestedAttribute, category) { PluginUtils.trace("ENTER getTagvalueAttributes [" + instanceName + "]"); var tagvalueSecurityLevelIdentifier = new AttributeIdentifier("tagvalue_securitylevel", Attribute.DataType.STRING, null); var securityLevelString = context.getAttribute(Attribute.Category.SUBJECT, tagvalueSecurityLevelIdentifier)[0]; // convert string to Integer var securityLevelInt = parseInt(securityLevelString); PluginUtils.trace("securityLevelInt: " + securityLevelInt); // write new attribute to context var securityLevelIdentifier = new AttributeIdentifier("urn:demo:securitylevel", Attribute.DataType.INTEGER, instanceName); context.addAttribute(securityLevelIdentifier, [securityLevelInt]); // Additional/multiple attributes could be added now too // For Example: var philipnyeAttributeIdentifier = new AttributeIdentifier("urn:demo:philipnye", Attribute.DataType.STRING, instanceName); context.addAttribute(philipnyeAttributeIdentifier, ["philipnye.com"]); PluginUtils.trace("EXIT getTagvalueAttributes [" + instanceName + "]"); }
Notes:
- PluginUtils.trace can be used to create tracing statements. This can be very helpful when performing more complex conversions or callouts. These will appear in the trace.log file:
when you have the appropriate levels of trace enabled:
- Returned attributes can take many different data formats, the full list of supported Datatypes is in the JavaScript documentation.
Create a new Policy Information Point
Navigate to Secure Mobile Settings -> Information Points.
And create a new JavaScript PIP definition.
Supply the following:
Ensuring the name of the PIP matches the Issuer of the attribute, and upload the script file.
Configuration Parameters
Want to know how to access the config parameters, see this short article:
ISAM AAC CBA PIPs – Accessing config options
Conclusion
This should be all the steps required to write your own custom Policy Information Point using JavaScript. If you still need more examples, remember you can download any of the preloaded JavaScript PIPs that come with the appliance!
Writing CBA policy can be very powerful, and it can also let you keep your users informed, in this example, I’ve created an obligation that can redirect the user to a suitable message page: