This guide describes how to extend the affiliation attribute with the member value and how to add six internationally used attributes, which are required by some international Federation Partners (e.g. publishers). SWITCH recommends to add these attributes as they will ensure that users in SWITCHaai can access international services and that international collaboration becomes easier. The latter especially applies for more and more research projects funded by the European Commission and other funding bodies.
The attributes that are recommended to add are:
The information contained in the above attributes is already available for all SWITCHaai Identity Providers. No changes in the Active Directory or LDAP Directory are needed because the above attributes are either the same for all users or they can be composed from already existing attribute values. Therefore, adding these attributes is only a matter of Identity Provider configuration.
Before starting the configuration, please complete the following form and click on the "Update" button. This allows generating custom-tailored configuration snippets in the sections below.
In order to release the international attributes, first adapt the Home Organisation description of the Identity Provider in the SWITCH Resource Registry.
This includes the following steps:
This will add the above-mentioned international attributes as supported attributes and set the default release scope to Federation for required attributes and Own Organization for desired attributes. This means that the attributes are by default released to all SWITCHaai services if they are required by a service. The attributes are however only released to services of the own organisation if they are just desired. Of course, this default policy can be changed in the Resource Registry.
The goal of the following steps is to configure the Identity Provider to release the International attributes declared as supported in the previous step. All these attributes are internationally standardized and easy to add because they can be composed of attributes, which are already available at your SWITCHaai Identity Provider.
The following attribute definitions partially use JavaScript. We have heard of users having some negative performance influence because of heavy use of such scripts. In case you have a heavily loaded IdP and performance might be an issue for you at all, you should do a performance test of your IdP in a test environment. You find more information about performance testing at the Shibboleth Wiki. In case of questions, ask the AAI Team at aai@switch.ch for assistance.
In order to support the additional attributes, the Shibboleth Identity Provider attribute resolver configuration has to be adapted like this:
cd /opt/shibboleth-idp/conf/ cp -p attribute-resolver.xml attribute-resolver.xml.bakThe backup file allows you to fall back to the current state of the Identity Provider in case something goes wrong.
<!-- Affiliation (eduPersonAffiliation) --> <resolver:AttributeDefinition id="eduPersonAffiliation" xsi:type="ad:Simple" sourceAttributeID="eduPersonAffiliation"> <resolver:Dependency ref="myLDAP" /> <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" friendlyName="eduPersonAffiliation" /> </resolver:AttributeDefinition>There are two options to add the member value: Either it is added to the user directory for each user individually, which is not only a one-time change but also is likely to affect the processes to register a new user. Or the member value is added by the Identity Provider based on the already available affiliation values.
<!-- Affiliation (eduPersonAffiliation) --> <resolver:AttributeDefinition xsi:type="ad:Mapped" id="eduPersonAffiliation" sourceAttributeID="eduPersonAffiliation"> <resolver:Dependency ref="myLDAP" /> <resolver:DisplayName xml:lang="en">Affiliation</resolver:DisplayName> <resolver:DisplayName xml:lang="de">Zugehörigkeit</resolver:DisplayName> <resolver:DisplayName xml:lang="fr">Affiliation</resolver:DisplayName> <resolver:DisplayName xml:lang="it">Tipo di membro</resolver:DisplayName> <resolver:DisplayDescription xml:lang="en"> Affiliation: Type of affiliation with Home Organization</resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="de">Art der Zugehörigkeit zur Heimorganisation</resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="fr">Type d'affiliation dans l'organisation</resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="it"> Tipo di membro: Tipo di lavoro svolto per l'organizzazione. </resolver:DisplayDescription> <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:eduPersonAffiliation" /> <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" friendlyName="eduPersonAffiliation" /> <ad:DefaultValue passThru="true"/> <ad:ValueMap> <ad:ReturnValue>member</ad:ReturnValue> <ad:SourceValue>staff|student|faculty|employee</ad:SourceValue> </ad:ValueMap> <ad:ValueMap> <ad:ReturnValue>$1</ad:ReturnValue> <ad:SourceValue>(staff|student|faculty|employee)</ad:SourceValue> </ad:ValueMap> </resolver:AttributeDefinition>Ensure that the Dependency is set correctly to the data connector that is used to get user attributes from. The default is myLDAP. The DisplayName and DisplayDescription elements are used in case your Identity Provider uses uApprove. Also note that if you already use a Script to set the affiliation value programmatically, you will have to adapt your existing script by adding the above if-clause as last statement.
To support these attribute, add the following XML snippets just after the last already existing <AttributeDefinition> element.
For some attributes, we provide two alternative definitions, depending on whether the source attribute is already available in your user directory or not (like e.g. commonName or displayName). In case the source attribute is not contained in the user directory, the attribute value is composed by other existing attributes by using JavaScript. Just use the definition that best matches your setup.
<!-- Common Name (commonName) --> <!-- Attribute commonName is contained in your LDAP directory: use the value from the LDAP directory --> <!-- <resolver:AttributeDefinition id="commonName" xsi:type="ad:Simple" sourceAttributeID="cn"> <resolver:Dependency ref="myLDAP" /> <resolver:DisplayName xml:lang="en">Common Name</resolver:DisplayName> <resolver:DisplayName xml:lang="de">Name</resolver:DisplayName> <resolver:DisplayName xml:lang="fr">Nom</resolver:DisplayName> <resolver:DisplayName xml:lang="it">Nome</resolver:DisplayName> <resolver:DisplayDescription xml:lang="en"> One or more names that should appear in white-pages-like applications for this person. </resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="de">Name</resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="fr">Nom</resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="it">Nome</resolver:DisplayDescription> <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.3" friendlyName="cn" /> </resolver:AttributeDefinition> --> <!-- Attribute commonName is not contained in your LDAP directory: Use the value of the attribute displayName --> <resolver:AttributeDefinition id="commonName" xsi:type="ad:Simple" sourceAttributeID="displayName"> <resolver:Dependency ref="displayName" /> <resolver:DisplayName xml:lang="en">Common Name</resolver:DisplayName> <resolver:DisplayName xml:lang="de">Name</resolver:DisplayName> <resolver:DisplayName xml:lang="fr">Nom</resolver:DisplayName> <resolver:DisplayName xml:lang="it">Nome</resolver:DisplayName> <resolver:DisplayDescription xml:lang="en"> One or more names that should appear in white-pages-like applications for this person. </resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="de">Name</resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="fr">Nom</resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="it">Nome</resolver:DisplayDescription> <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.3" friendlyName="cn" /> </resolver:AttributeDefinition> <!-- Display Name (displayName) --> <!-- Attribute displayName is contained in your LDAP directory: use the value from the LDAP directory --> <!-- <resolver:AttributeDefinition id="displayName" xsi:type="ad:Simple" sourceAttributeID="displayName"> <resolver:Dependency ref="myLDAP" /> <resolver:DisplayName xml:lang="en">Display Name</resolver:DisplayName> <resolver:DisplayName xml:lang="de">Anzeigename</resolver:DisplayName> <resolver:DisplayName xml:lang="fr">Nom</resolver:DisplayName> <resolver:DisplayName xml:lang="it">Nome</resolver:DisplayName> <resolver:DisplayDescription xml:lang="en"> The name that should appear in white-pages-like applications for this person. </resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="de">Anzeigename</resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="fr">Nom</resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="it">Nome</resolver:DisplayDescription> <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.16.840.1.113730.3.1.241" friendlyName="displayName" /> </resolver:AttributeDefinition> --> <!-- Attribute displayName is not contained in your LDAP directory: compose the value with JavaScript --> <resolver:AttributeDefinition id="displayName" xsi:type="ad:Script"> <resolver:Dependency ref="givenName" /> <resolver:Dependency ref="surname" /> <resolver:DisplayName xml:lang="en">Display Name</resolver:DisplayName> <resolver:DisplayName xml:lang="de">Anzeigename</resolver:DisplayName> <resolver:DisplayName xml:lang="fr">Nom</resolver:DisplayName> <resolver:DisplayName xml:lang="it">Nome</resolver:DisplayName> <resolver:DisplayDescription xml:lang="en"> The name that should appear in white-pages-like applications for this person. </resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="de">Anzeigename</resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="fr">Nom</resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="it">Nome</resolver:DisplayDescription> <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.16.840.1.113730.3.1.241" friendlyName="displayName" /> <ad:Script> <![CDATA[ importPackage(Packages.edu.internet2.middleware.shibboleth.common.attribute.provider); // This implementation composes the value of the attribute displayName // from the values of the attributes givenName and surname. // Initialize displayName displayName = new BasicAttribute("displayName"); // compose value from givenName and surname // check whether givenName and surname exist if (givenName != null && givenName.getValues().size() > 0) { gn = givenName.getValues().get(0); } else { gn = null; } if (surname != null && surname.getValues().size() > 0) { sn = surname.getValues().get(0); } else { sn = null; } if (sn != null && gn != null) { displayName.getValues().add( gn + " " + sn ); } else if (sn != null) { displayName.getValues().add( sn ); } else if (gn != null) { displayName.getValues().add( gn ); } ]]> </ad:Script> </resolver:AttributeDefinition> <!-- Principal name (eduPersonPrincipalName) --> <!-- Use the same value as the attribute swissEduPersonUniqueID --> <resolver:AttributeDefinition id="eduPersonPrincipalName" xsi:type="ad:Simple" sourceAttributeID="swissEduPersonUniqueID"> <resolver:Dependency ref="swissEduPersonUniqueID" /> <resolver:DisplayName xml:lang="en">Principal Name</resolver:DisplayName> <resolver:DisplayName xml:lang="de">Principal Name</resolver:DisplayName> <resolver:DisplayName xml:lang="fr">Principal Name</resolver:DisplayName> <resolver:DisplayName xml:lang="it">Principal Name</resolver:DisplayName> <resolver:DisplayDescription xml:lang="en"> A unique identifier for a person, mainly for inter-institutional user identification. </resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="de"> Eindeutige Benützeridentifikation </resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="fr"> L'identifiant unique de l'utilisateur au seins de l'AAI. </resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="it"> Un ID personale che identifica chiaramente l'utente in seno alla sua organizzazione </resolver:DisplayDescription> <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" friendlyName="eduPersonPrincipalName" /> </resolver:AttributeDefinition> <!-- SCHAC Home Organisation (schacHomeOrganization) --> <resolver:AttributeDefinition id="schacHomeOrganization" xsi:type="ad:Simple" sourceAttributeID="schacHomeOrganization"> <resolver:Dependency ref="staticAttributes" /> <resolver:DisplayName xml:lang="en">Home organization</resolver:DisplayName> <resolver:DisplayName xml:lang="de">Heimorganisation</resolver:DisplayName> <resolver:DisplayName xml:lang="fr">Organisation</resolver:DisplayName> <resolver:DisplayName xml:lang="it">Nome dell'organizzazione</resolver:DisplayName> <resolver:DisplayDescription xml:lang="en"> Home Organization: Domain name of a Home Organization </resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="de"> Domain Name der Heimorganisation </resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="fr"> Nom de domaine de l'organisation: uzh.ch, unil.ch, ... </resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="it"> Nome dell'organizzazione come per esempio: uzh.ch, unil.ch, ... </resolver:DisplayDescription> <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.25178.1.2.9" friendlyName="schacHomeOrganization" /> </resolver:AttributeDefinition> <!-- SCHAC Home Organisation Type (schacHomeOrganizationType) --> <!-- first value: swissEduPersonHomeOrganizationType attribute prefixed by "urn:schac:homeOrganizationType:ch:" second value: an internationally standardized value, where applicable --> <resolver:AttributeDefinition id="schacHomeOrganizationType" xsi:type="ad:Mapped" sourceAttributeID="swissEduPersonHomeOrganizationType"> <resolver:Dependency ref="staticAttributes" /> <resolver:DisplayName xml:lang="en">Home organization type (international)</resolver:DisplayName> <resolver:DisplayName xml:lang="de">Typ der Heimorganisation (international)</resolver:DisplayName> <resolver:DisplayName xml:lang="fr">Type d'Organisation (international)</resolver:DisplayName> <resolver:DisplayName xml:lang="it">Tipo dell'organizzazione di appartenenza (internazionale)</resolver:DisplayName> <resolver:DisplayDescription xml:lang="en"> Home Organization Type: Type of a Home Organization </resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="de">Kategorie der Heimorganisation</resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="fr">Le type d'organisation</resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="it">Tipo dell'organizzazione di appartenenza</resolver:DisplayDescription> <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:terena.org:schac:schacHomeOrganizationType" /> <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.25178.1.2.10" friendlyName="schacHomeOrganizationType" /> <ad:ValueMap> <ad:ReturnValue>urn:schac:homeOrganizationType:ch:$1</ad:ReturnValue> <ad:SourceValue>(.+)</ad:SourceValue> </ad:ValueMap> <ad:ValueMap> <ad:ReturnValue>urn:schac:homeOrganizationType:eu:higherEducationalInstitution</ad:ReturnValue> <ad:SourceValue>university|uas|tertiaryb</ad:SourceValue> </ad:ValueMap> <ad:ValueMap> <ad:ReturnValue>urn:schac:homeOrganizationType:eu:educationalInstitution</ad:ReturnValue> <ad:SourceValue>uppersecondary</ad:SourceValue> </ad:ValueMap> </resolver:AttributeDefinition> <!-- Scoped affiliation (eduPersonScopedAffiliation) --> <resolver:AttributeDefinition id="eduPersonScopedAffiliation" xsi:type="ad:Scoped" scope="####YOUR_ORGANIZATION_DOMAIN_NAME###" sourceAttributeID="eduPersonAffiliation"> <resolver:Dependency ref="eduPersonAffiliation" /> <resolver:DisplayName xml:lang="en">Affiliation</resolver:DisplayName> <resolver:DisplayName xml:lang="de">Zugehörigkeit</resolver:DisplayName> <resolver:DisplayName xml:lang="fr">Affiliation</resolver:DisplayName> <resolver:DisplayName xml:lang="it">Tipo di membro</resolver:DisplayName> <resolver:DisplayDescription xml:lang="en"> Affiliation: Type of affiliation with Home Organization </resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="de"> Art der Zugehörigkeit zur Heimorganisation </resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="fr"> Type d'affiliation dans l'organisation </resolver:DisplayDescription> <resolver:DisplayDescription xml:lang="it"> Tipo di membro: Tipo di lavoro svolto per l'organizzazione. </resolver:DisplayDescription> <resolver:AttributeEncoder xsi:type="enc:SAML2ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.9" friendlyName="eduPersonScopedAffiliation" /> </resolver:AttributeDefinition>The above snippets will add attribute definitions of all attributes that are recommended to support. Make sure that the scope of the eduPersonScopedAffiliation is set to your organization's domain name (e.g. ethz.ch, unige.ch, phlu.ch, ...).
<dc:Attribute id="schacHomeOrganization"> <dc:Value>####YOUR_ORGANIZATION_DOMAIN_NAME###</dc:Value> </dc:Attribute>
<!-- Static Connector --> <resolver:DataConnector id="staticAttributes" xsi:type="dc:Static"> <dc:Attribute id="schacHomeOrganization"> <dc:Value>####YOUR_ORGANIZATION_DOMAIN_NAME###</dc:Value> </dc:Attribute> </resolver:DataConnector>
The Identity Provider should now be ready to restart:
xmlwf attribute-resolver.xmlIf no output is shown, the configuration files are well-formed. Alternatively, it is also possible to open the files in Firefox, which will display a warning message if a file is not well-formed.
$ /etc/init.d/tomcat* restart
$ tail -f /var/log/shibboleth/idp-process.logCheck that there are no ERROR, CRIT or WARN messages during startup. If there are, you might want to restart the Identity Provider again with the backup version of attribute-resolver.xml
In order to ensure that the Identity Provider configuration was applied correctly, perform the following test:
This section lists some common problems and possible solutions.