The Shibboleth IdP V4 software will leave support on September 1, 2024.

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 20 Next »

Namespace: urn:mace:shibboleth:2.0:resolver
Schema: http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd

Overview

The ScriptedAttribute AttributeDefinition constructs an output attribute via the execution of a JSR-223 script. Scripts are somewhat easier to write and maintain than native Java code, though they are slower. They can also be changed dynamically since the resolver is a ReloadableService.

Scripting

Reference

V2 Compatibility

This support is deprecated and should have been removed in V4, however the change was not warned about sufficiently. This will be removed in V5.

In order to support the majority of scripts written for V2, the runtime environment is extended in two ways:

  • A package named edu.internet2.middleware.shibboleth.common.attribute.provider is available, and specifically within it, the BasicAttribute class. This provides a facsimile of the V2-equivalent class. Specifically:

    • A constructor which takes a String, being the name of the attribute being created.

    • The getValues() method which returns the current values.

  • A variable named requestContext  which implements all the methods implemented by the V2 class "edu.internet2.middleware.shibboleth.common.profile.provider.BaseSAMLProfileRequestContext". However, all but three of these methods do nothing but log an error and (where a return value is required) return a null pointer. The three methods which are implemented are:

    • getPrincipalName to provide identification of the subject 

    • getPeerEntityId to get the entityId of the attribute recipient

    • getLocalEntityId to get the entityId of the attribute issuer

    In V3, all of this information is also available in the AttributeResolutionContext to eliminate the dependency on the legacy interface.

It is expected that the addition of this emulation code will allow the majority of V2 scripts to run unchanged. All of the examples in the V2 wiki topic run unchanged (subject to the constraints introduced by Java 1.8). Nonetheless, users should consider rewriting their scripts after upgrading, as this capability will likely be removed in V4.

Nashorn

In Java 1.8 through Java 14, the Nashorn scripting engine provides the default "JavaScript" language. This has some syntactic (explained here) and semantic differences from the older Rhino engine.  To convert a working V2, pre-Java 1.8 script to IdPV4 running Java 11:

  • Make the syntactic changes required.

  • Remove the now-redundant creation of the output attribute (In V4 the output attribute is pre-created).  If the script needs to run under both versions:

    if (null == scriptedAttribute) {
        // will only occurr under IdP V2, running pre-Java 1.8
        scriptedAttribute = new BasicAttribute("scriptedAttribute");
    }

Of course, for new scripts created for V4 alone, this isn't necessary.

Examples

Get eduPersonPrincipalName from LDAP or build one from uid

Variant 1: A "Prescoped" AttributeDefinition resolves existing eduPersonPrincipalName values from LDAP, then depends on a "ScriptedAttribute" definition to generate missing values. The Script also needs a dependency on the myLDAP DataConnector in order to have access to existing eduPersonPrincipalName and uid attribute values.

Minimal scripting, using Dependencies (Nashorn)
<AttributeDefinition id="eduPersonPrincipalName" xsi:type="Prescoped">
	<InputAttributeDefinition ref="eppnFromUid" />
</AttributeDefinition>

<AttributeDefinition id="eppnFromUid" xsi:type="ScriptedAttribute" dependencyOnly="true">
    <InputDataConnector ref="myLDAP" attributeNames="eduPersonPrincipalName uid" />
    <Script><![CDATA[
	if (typeof eduPersonPrincipalName == "undefined") eppnFromUid.addValue(uid.getValues().get(0) + "@%{idp.scope}");
	]]></Script>
</AttributeDefinition>

Variant 2: Doing everything in one "ScriptedAttribute" definition. Since the eduPersonPrincipalName values from LDAP will contain the scope but are simple strings at this point, we'll have to empty out the collection of values before adding the properly scope-aware values based on ScopedStringAttributeValue (described above).

All in one Script (Nashorn)
<AttributeDefinition id="eduPersonPrincipalName" xsi:type="ScriptedAttribute">
    <InputDataConnector ref="myLDAP" attributeNames="eduPersonPrincipalName uid" />

    <Script><![CDATA[
logger = Java.type("org.slf4j.LoggerFactory").getLogger("org.example.eppnbuilder");
scopedValueType =  Java.type("net.shibboleth.idp.attribute.ScopedStringAttributeValue");
var localpart = "";
if (typeof eduPersonPrincipalName == "undefined" || eduPersonPrincipalName.getValues().size() < 1) {
    logger.debug("No ePPN in LDAP found, creating one");
    localpart = uid.getValues().get(0);
} else {
    logger.debug("ePPN had value: " + eduPersonPrincipalName.getValues().get(0));
    localpart = eduPersonPrincipalName.getValues().get(0).split("@")[0];
    eduPersonPrincipalName.getValues().retainAll([]);
}
eduPersonPrincipalName.addValue(new scopedValueType(localpart, "%{idp.scope}"));
logger.debug("ePPN final value: " + eduPersonPrincipalName.getValues().get(0));
    ]]></Script>
</AttributeDefinition>

  • No labels