Using Azure Entra ID Groups with Scripted Attributes to Enable eduPersonAffiliation in Shibboleth IdP

Using Azure Entra ID Groups with Scripted Attributes to Enable eduPersonAffiliation in Shibboleth IdP

Overview

This guide describes how to use Azure (Entra ID) groups with Shibboleth's ScriptedAttributeDefinition to populate the eduPersonAffiliation attribute, which in turn supports the scoped version: eduPersonScopedAffiliation

These attributes follow the eduPerson schema specification and typically contain multiple values (e.g., member@example.com, student@example.com). Scoped values are defined using the domain chosen during the initial IdP installation (e.g., @example.com). 

Why Use ScriptedAttributeDefinition?

Using ScriptedAttributeDefinition allows for advanced mapping logic that cannot be expressed through static AttributeResolver maps. It is especially useful when:

  • Users belong to multiple Azure groups.

  • Group-to-affiliation mapping varies based on multiple conditions.

  • Dynamic or context-aware logic is needed.

Note: Scripted attributes require JavaScript knowledge and effective logging. Poorly written scripts may introduce unexpected behavior.

 Prerequisites

Before proceeding, ensure that: You have read the following:

<AttributeDefinition id="eduPersonAffiliation" xsi:type="ScriptedAttribute"> <InputDataConnector ref="passthroughAttributes" attributeNames="azureGroups"/> <Script> <![CDATA[ // This script maps Azure group claims to eduPersonAffiliation values var IdPAttribute = Java.type("net.shibboleth.idp.attribute.IdPAttribute"); var StringAttributeValue = Java.type("net.shibboleth.idp.attribute.StringAttributeValue"); var logger = Java.type("org.slf4j.LoggerFactory").getLogger("net.shibboleth.idp.attribute"); var groupToAffiliationMap = { "abc123a-555e-test-86df-random-object-value": "faculty", "xyz890zbs-52test-a41e5-random-object-value": "staff", "AzureGroup3": "employee", "AzureGroup4": "student" }; if (typeof azureGroups !== "undefined" && azureGroups !== null) { var groupValues = azureGroups.getValues(); for (var i = 0; i < groupValues.size(); i++) { var group = groupValues.get(i).toString(); var affiliation = groupToAffiliationMap[group]; logger.info("Adding Affiliation as " + affiliation); if (affiliation !== null && typeof affiliation !== "undefined") { eduPersonAffiliation.addValue(new StringAttributeValue(affiliation)); } } } ]]> </Script> </AttributeDefinition>

 

Other technique exemplar:

<AttributeDefinition id="eduPersonAssurance" xsi:type="ScriptedAttribute"> <InputDataConnector ref="passthroughAttributes" attributeNames="azureGroups" /> <Script> <![CDATA[ if (typeof azureGroups != "undefined" && azureGroups != null) { if (!(azureGroups.getValues().contains("IAP-Zero"))) { eduPersonAssurance.getValues().add(" https://refeds.org/assurance/IAP/local-enterprise"); } if (azureGroups.getValues().contains("IAP-Low")) { eduPersonAssurance.getValues().add(" https://refeds.org/assurance/IAP/low"); } if (azureGroups.getValues().contains("IAP-Medium")) { eduPersonAssurance.getValues().add(" https://refeds.org/assurance/IAP/medium"); } if (azureGroups.getValues().contains("IAP-High")) { eduPersonAssurance.getValues().add(" https://refeds.org/assurance/IAP/high"); } } ]]> </Script> </AttributeDefinition>

Final Notes

This method provides a flexible and powerful way to tailor attribute values based on Azure group membership. It is especially helpful for institutions with diverse affiliation logic not suited to static mapping.

For simpler needs, consider using basic mapped attributes instead of scripting.

Filter by label

There are no items with the selected labels at this time.