Scripting NetIQ Access Manager Policy Extensions in Groovy


Policy Types and Extensions

There are different type of policies in NetIQ Access Manager, namely Authorization Policies, ID Injection Policies, Form Fill Policies, Role Assignment Policies and External Attributes Policies. The existing capabilities in Access Manager will suit for most of the general use cases. But sometimes it is necessary to write some custom code to extend the default functionality provided by Access Manager.

For example, some of the user's attributes could be stored in a database or x509 directories. NetIQ Access Manager does not support reading from those stores directly other than the LDAP-compatible directories. In that case, an External Attribute Policy Extension can be written using Java code and integrated with NetIQ Access Manager. For more information on NetIQ Access Manager policies, refer to the Policy Guide

Extension Types

There are basically three types of policy extensions in NetIQ Access Manager:

  • Data Extension

  • Condition Extension

  • Action Extension

Data Extensions provide some form data which can be used in Identity Injections and External Attributes Policies wherever data is expected. Condition Extensions are used in Authorization policies as logical decision steps to decide on authorization outcome. Action Extensions are used in Authorization policies to write custom actions when all the authorization conditions are satisfied, for example, the custom action could send an alert or email when a condition is met.

Writing Extensions in Java

For writing an extension, it has to go through multiple steps. Basically, a factory class has to be written for each type of extension. This factory class will be used to “instantiate” the actual policy extension objects. The actual policy extension class has to implement the necessary interface to provide necessary data to the policy engine in NetIQ Access Manager.

The data that is returned from the extension depends on the type of extension. Data extensions should return a object that can be serialized to a string, i.e. should have a toString method which gives a string representation of the object.

For example, if the extension is to return current Time, either return a String or an Object which has the toString method. For Condition Extensions, the extension should return either NxpeResult.ConditionTrue or NxpeResult.ConditionFalse. After writing extensions, the compiled jar has to be uploaded to the Administration Console, and you need to configure the policy for the right type of policy and configure the parameters to be injected into the extension to make a decision.

Writing Extension in Groovy

It will be convenient if the extensions can be written in a scripting language. With scripting engines, the code need not be compiled. The compilation happens at runtime. After changing the code, it is not required to restart the server process to take effect. The script can be dynamically changed after it is deployed and can be changed by anyone with a minimum knowledge on groovy scripting.

Also with a groovy-based policy extension, the same jar and class can be used to create multiple policy extensions and change only the script.

Steps to write groovy scripts for Policy Extensions

  1. Login into Administration Console.

  • Upload the attached jar file to Administration console, by going to menu “Policies ? Extensions ? Upload”. Select path of GroovyPolicyExtensions-3.2.jar. And click OK.

  • Create a new Extension by clicking “New.”

  • Give a name to the policy extension and fill in the following details.Name: <Name of extension> e.g. EmailFromDB

    PolicyType: <type of policy> e.g. Identity Server External Attributes. Use Identity Inject if using for Identity Injection. Use “Authorization Policy” for authorization

    Type: Data (Use Condition for Authorization Policy)

    ClassName: GroovyScriptDataElementFactory.class(use GroovyConditionFactory.class for Authorization)

    Filename: GroovyPolicyExtensions-3.2.jar

  • Click the link on your newly created policy.

  • Click New on Configuration Parameters.Name: SCRIPT

    ID: 100 (This has to be 100. The GroovyScripts extension always refers to id 100)

    Click OK. Then,

    Select dropdown on “mapping”. Select “String constant”. And give the script name to be executed when invoking this extension. e.g. email_from_db.groovy. The policy engine runtime will look for this script at /var/opt/novell/scripts/ folder.

  • Additional parameters can be passed to script in variables. For that, again click “New” in Configuration Parameters and give a “groovy valid variable identifier name” for “Name”. The id can be anything other than 100. e.g. email. In the script, this parameter can be read as just a plain groovy variable. The variable will be bound during runtime to the value selected on the mapping dropdown. For example, the “Ldap Attribute” ? cn can be bound to “cn” named parameter. There are two types of variables are possible in using this binding. The  input object might be a string, or a String[] array if it is a multivalued attribute. For a single value, this can be referenced as just the variable, the array can be referenced as “(cn as Set)” inside the groovy script.

  • Steps 3 - 7 can be repeated for different type of extensions.

  • Create either a Identity Injection policy or External Attribute policy as per your need, by clicking from tom “Policies ? New ? <policy name> ? type: Identity Injection or External Data Attribute”

  • For External Attribute policies, go to “Identity Servers ? Edit ? External Attributes”. Enable the policies that were created above.

  • For Identity Injection, “Access Gateways ? Edit ? Proxy Service ? Protected Resources ? Identity Injection” for the right URL pattern and click Enable.

  • The GroovyExtension.jar has to be distributed to the devices if it is not done already or if a new version has been uploaded. For this, go to “Policies ? Extensions”, check the necessary policies, and click “Distribute Jar."

  • Since this uses groovy extensions, a new jar has to uploaded manually. Download the groovy distribution “bundle” from “”. And copy only the “groovy-all-2.2.2.jar” from zip folder “groovy-2.2.2/embeddable/”.

  • The groovy runtime jars have to distributed to each node either Identity Provider or Access Gateway manually. Copy the groovy-all-2.2.2.jar to “/opt/novell/nam/idp/webapps/nidp/WEB-INF/lib” for Identity Provider machines and “/opt/novell/nam/mag/webapps/nesp/WEB-INF/lib” folder for Access Gateway.

  • Create a folder /var/opt/novell/scripts/ if it doesn't exist already. Change the permissions to this folder that only “root” user can write and make sure that user “novlwww” can read the folder. See security considerations in this article.

  • You can start writing your groovy scripts for your business logic. For example, the following script is a Data extension which simply injects time.
    // time.groovy

    result = new Date().toString()

    Assigning to a variable “result” is important, this is how the policy engine knows what the result is.

    The following is a data extension which takes mail as a parameter and manipulates it:
    // mail.groovy

    result = "emailid is ${mail as Set}".toString()

    Since, mail is a multivalued attribute, it should read as a string array. A “configuration parameter” named “mail” has to be configured as specified in step 7 above. The data extension can return any object that can be converted into string.

    The following is a condition extension
    //cn = admin

    //has_value = "b"

    println "groovy: ${cn}"

    println "groovy: ${has_value}"

    result = cn.contains(has _value)

    println "groovy: ${result}"

    The condition extensions should return either “true” or “false”. “cn” and “has_value” should be configured as “Configuration Parameters” with same name in Administration Console. “cn” should be mapped to “Ldap Attribute:cn” and “has_value” should be mapped to “String Constant” with your chosen value.

    The following is a little more complex idiom to search a list of emails whether it contains a string.
    //mail = ["abds"]

    //has_value = "b"

    println "groovy: ${mail}"

    println "groovy: ${has_value}"

    result = (mail as Set).inject(false) {prev, current -> prev || current.contains(has _value)}

    println "groovy: ${result}"

    You can uncomment the commented lines to test your script with sample values before testing with policy extension. The println results will end up in catalina.out.

Security Considerations

Since the script with the name specified in policy is compiled and executed at run-time, the script and the folder has to be protected from malicious modification. The Java jar in Identity providers are protected by Digital Signatures. The same cannot be applied to Groovy Scripts. So, here are some security considerations.

  1. Strip off write permission other than root.chown -R root.root /var/opt/novell/scripts

    chmod u-w /var/opt/novell/scripts

    chmod o-w /var/opt/novell/scripts

  • And of course, keep the root pwd secure only administrator can login into the system.


How To-Best Practice
Comment List