Script Attribute Definition

The script attribute definition allows attributes to be constructed by the execution of a JSR-223 supported script. Currently only ECMAScript (previously known as Javascript) is supported in a default IdP distribution. Others may be added, however.

If your IdP is clustered using Terracotta, you may experience out of memory conditions due to the Javascript optimizer creating lots of temporary classes. You can work around this by replacing lib/rhino-V###.jar in the IdP distribution with a copy of the .jar with the org/mozilla/javascript/optimizer directory removed.

1. Define the Definition

The definition is defined with the element <resolver:AttributeDefinition xsi:type="Script" xmlns="urn:mace:shibboleth:2.0:resolver:ad"> with the following required attribute:

and the following optional attribute:

<resolver:AttributeDefinition xsi:type="Script" xmlns="urn:mace:shibboleth:2.0:resolver:ad"
                              id="UNIQUE_ID">

     <!-- Remaining configuration from the next step go here -->

</resolver:AttributeDefinition>

2. Define Dependencies

It is very common for one component, like attribute definitions, within the attribute resolver to depend on information retrieved or constructed from another component.

Dependencies are expressed by the <resolver:Dependency> with a ref attribute whose value is the unique ID of the attribute definition or the data connector that this connector depends on.

<resolver:AttributeDefinition xsi:type="Script" xmlns="urn:mace:shibboleth:2.0:resolver:ad"
                              id="UNIQUE_ID">

     <resolver:Dependency ref="DEFINITION_ID_1" />
     <resolver:Dependency ref="DEFINITION_ID_2" />
     <resolver:Dependency ref="CONNECTOR_ID_3" />
     <resolver:Dependency ref="CONNECTOR_ID_4" />

     <!-- Remaining configuration from the next step go here -->

</resolver:AttributeDefinition>

3. Define the Script

The script to be executed may be referenced in one of two ways, both represented as an element contained in the <resolver:AttributeDefinition> element. The <Script> element allows a script to defined inline, that is the content of the element is the script itself. Alternatively the <ScriptFile> element defines the location, on the filesystem, of a file containing the script to be executed.

Some scripting languages place certain restrictions on variable names (e.g. may not contain a "-"). Ensure that any attribute you wish to use does not contain such an illegal character in its ID. If it does use a Simple Attribute Definition to create a new attribute, with a different ID, whose source attribute is the attribute with the problematic ID.

<resolver:AttributeDefinition xsi:type="Script" xmlns="urn:mace:shibboleth:2.0:resolver:ad"
                              id="fullName">

     <!-- Dependency information would go here -->

    <Script><![CDATA[
        importPackage(Packages.edu.internet2.middleware.shibboleth.common.attribute.provider);

        fullname = new BasicAttribute("fullname");
        fullname.getValues().add(givenName.getValues().get(0) + " " + sn.getValues().get(0));
    ]]></Script>
</resolver:AttributeDefinition>
<resolver:AttributeDefinition xsi:type="Script" xmlns="urn:mace:shibboleth:2.0:resolver:ad"
                              id="UNIQUE_ID" >

    <!-- Dependency information would go here -->

    <ScriptFile>/usr/local/shibboleth-idp/script/myScript.js</ScriptFile>

</resolver:AttributeDefinition>

Information Available to the Script

The following information is made available to an executing script:

Except in the specific case noted in IdPJava1.8 attribute should never be modified by scripts since this will yield undefined results.

Logging Within a Script

The same logging framework used throughout the IdP (SLF4J) may also be used for logging within a script. First import the package org.slf4j and then obtain an org.slf4j.Logger object from an org.slf4j.LoggerFactory. The logging category name used is arbitrary, but must be consistent with the IdP's logging configuration. Logging levels available are: error, warn, info, debug, trace.
The string passed to the LoggerFactory.getLogger method should be the name of an existing logger element, defined in logging.xml.

For more information on configuring logging within the IdP, see the IdP Logging topic.

 <resolver:AttributeDefinition xsi:type="Script" xmlns="urn:mace:shibboleth:2.0:resolver:ad" 
                              id="scriptTest">
    <Script><![CDATA[
        importPackage(Packages.edu.internet2.middleware.shibboleth.common.attribute.provider);
        importPackage(Packages.org.slf4j);

        logger = LoggerFactory.getLogger("edu.internet2.middleware.shibboleth.resolver.Script.scriptTest");

        scriptTest = new BasicAttribute("scriptTest");
        scriptTest.getValues().add("foo");
        scriptTest.getValues().add("bar");

        logger.info("Values of scriptTest were: " + scriptTest.getValues());
    ]]></Script>
</resolver:AttributeDefinition>

Java8

Java 8 introduced an incompatible scripting language.  In nearly all cases updating to java 8 will require configuration changes.  This is discussed here.

Examples

Addition examples are also available. These provide more complete examples and are contributed by users of the software.

Example 1

Generates an opaque identifier from an attribute.

Example 2

Generates eduPersonAffiliation based on group membership.

Example 3

Adds common-lib-terms to eduPersonEntitlement based on the user's affiliation.