Created
August 7, 2025 08:45
-
-
Save daserzw/f6322941a7a6fd62c6e6a701d0357eef to your computer and use it in GitHub Desktop.
Shib IdP attribute-resolver.xml with variable scope based on schacHomeOrganization value
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?xml version="1.0" encoding="UTF-8"?> | |
| <AttributeResolver | |
| xmlns="urn:mace:shibboleth:2.0:resolver" | |
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
| xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd"> | |
| <!-- ========================================== --> | |
| <!-- Attribute Definitions --> | |
| <!-- ========================================== --> | |
| <!-- Default Shibboleth | |
| <AttributeDefinition scope="%{idp.scope}" xsi:type="Scoped" id="eduPersonScopedAffiliation"> | |
| <InputDataConnector ref="myLDAP" attributeNames="eduPersonAffiliation" /> | |
| </AttributeDefinition> | |
| --> | |
| <!-- eduPersonScopedAffiliation multi-scope with schacHomeOrganization START --> | |
| <AttributeDefinition id="prescopedEPSA" xsi:type="ScriptedAttribute" dependencyOnly="true"> | |
| <InputDataConnector ref="myLDAP" attributeNames="eduPersonAffiliation schacHomeOrganization"/> | |
| <Script> | |
| <![CDATA[ | |
| logger = Java.type("org.slf4j.LoggerFactory").getLogger("net.shibboleth.idp.attribute.resolver.preScopedEpsaBuilder"); | |
| for (n in eduPersonAffiliation.getValues()) { | |
| prescopedEPSA.addValue(eduPersonAffiliation.getValues().get(n) + '@' + schacHomeOrganization.getValues().get(0)); | |
| } | |
| ]]> | |
| </Script> | |
| </AttributeDefinition> | |
| <AttributeDefinition xsi:type="Prescoped" id="eduPersonScopedAffiliation"> | |
| <InputAttributeDefinition ref="prescopedEPSA" /> | |
| </AttributeDefinition> | |
| <!-- eduPersonScopedAffiliation multi-scope END --> | |
| <!-- Default Shibboleth | |
| <AttributeDefinition scope="%{idp.scope}" xsi:type="Scoped" id="eduPersonPrincipalName"> | |
| <InputDataConnector ref="myLDAP" attributeNames="%{idp.persistentId.sourceAttribute}" /> | |
| </AttributeDefinition> | |
| --> | |
| <!-- eduPersonPrincipalName multi-scope with schacHomeOrganization START --> | |
| <AttributeDefinition xsi:type="Template" id="prescopedEPPN"> | |
| <InputDataConnector ref="myLDAP" attributeNames="schacHomeOrganization %{idp.persistentId.sourceAttribute}" /> | |
| <Template>${%{idp.persistentId.sourceAttribute}}@${schacHomeOrganization}</Template> | |
| </AttributeDefinition> | |
| <AttributeDefinition xsi:type="Prescoped" id="eduPersonPrincipalName"> | |
| <InputAttributeDefinition ref="prescopedEPPN" /> | |
| </AttributeDefinition> | |
| <!-- eduPersonPrincipalName multi-scope END --> | |
| <!-- AttributeDefinition for eduPersonTargetedID - Computed Mode --> | |
| <AttributeDefinition xsi:type="SAML2NameID" nameIdFormat="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" id="eduPersonTargetedID"> | |
| <InputDataConnector ref="myComputedId" attributeNames="computedID"/> | |
| </AttributeDefinition> | |
| <AttributeDefinition xsi:type="Simple" id="schacHomeOrganizationType"> | |
| <InputDataConnector ref="staticAttributes" attributeNames="schacHomeOrganizationType"/> | |
| </AttributeDefinition> | |
| <!-- Schema: SAML Subject ID Attributes --> | |
| <!-- Default Shibboleth | |
| <AttributeDefinition xsi:type="Scoped" id="samlSubjectID" scope="%{idp.scope}"> | |
| <InputDataConnector ref="myLDAP" attributeNames="%{idp.persistentId.sourceAttribute}"/> | |
| </AttributeDefinition> | |
| --> | |
| <!-- SAML Subject ID multi-scope with schacHomeOrganization START --> | |
| <AttributeDefinition xsi:type="Template" id="prescopedsamlSubjectID"> | |
| <InputDataConnector ref="myLDAP" attributeNames="schacHomeOrganization %{idp.persistentId.sourceAttribute}" /> | |
| <Template>${ %{idp.persistentId.sourceAttribute} }@${schacHomeOrganization}</Template> | |
| </AttributeDefinition> | |
| <AttributeDefinition xsi:type="Prescoped" id="samlSubjectID"> | |
| <InputAttributeDefinition ref="prescopedsamlSubjectID" /> | |
| </AttributeDefinition> | |
| <!-- SAML Subject ID multi-scope with schacHomeOrganization END --> | |
| <!-- Default Shibboleth | |
| <AttributeDefinition xsi:type="Scoped" id="samlPairwiseID" scope="%{idp.scope}"> | |
| <InputDataConnector ref="myComputedId" attributeNames="computedID"/> | |
| </AttributeDefinition> | |
| --> | |
| <!-- SAML Pairwise ID multi-scope with schacHomeOrganization START --> | |
| <AttributeDefinition xsi:type="Template" id="prescopedsamlPairwiseID"> | |
| <InputDataConnector ref="myComputedId" attributeNames="computedID"/> | |
| <InputDataConnector ref="myLDAP" attributeNames="schacHomeOrganization" /> | |
| <Template>${computedID}@${schacHomeOrganization}"</Template> | |
| </AttributeDefinition> | |
| <AttributeDefinition xsi:type="Prescoped" id="samlPairwiseID"> | |
| <InputAttributeDefinition ref="prescopedsamlPairwiseID" /> | |
| </AttributeDefinition> | |
| <!-- SAML Pairwise ID multi-scope with schacHomeOrganization END --> | |
| <!-- schacPersonalUniqueCode multi-scope with schacHomeOrganization START --> | |
| <!-- | |
| <AttributeDefinition id="schacPersonalUniqueCode" xsi:type="Template"> | |
| <InputDataConnector ref="myLDAP" attributeNames="cn schacHomeOrganization"/> | |
| <Template>urn:schac:personalUniqueCode:int:esi:${schacHomeOrganization}:${cn}</Template> | |
| </AttributeDefinition> | |
| --> | |
| <!-- schacPersonalUniqueCode multi-scope with schacHomeOrganization END --> | |
| <AttributeDefinition id="displayName" xsi:type="ScriptedAttribute"> | |
| <InputDataConnector ref="myLDAP" attributeNames="displayName cn givenName sn" /> | |
| <Script> | |
| <![CDATA[ | |
| logger = Java.type("org.slf4j.LoggerFactory").getLogger("net.shibboleth.idp.attribute.resolver.displayNameBuilder"); | |
| valueType = Java.type("net.shibboleth.idp.attribute.StringAttributeValue"); | |
| // This implementation composes the value of the attribute displayName | |
| // from the values of the attributes givenName and surname. | |
| // check existance of commonName attribute and use it to generate displayName attribute | |
| if (cn != null && cn.getValues().size() > 0) { | |
| commonName = cn.getValues().get(0); | |
| } else { | |
| commonName = null; | |
| } | |
| // 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 (sn != null && sn.getValues().size() > 0) { | |
| surname = sn.getValues().get(0); | |
| } else { | |
| surname = null; | |
| } | |
| if (typeof displayName == 'undefined' || displayName.getValues().size() < 1) { | |
| //logger.info("No displayName in LDAP found, creating one"); | |
| if (cn != null) { | |
| displayName.addValue(new valueType(commonName)); | |
| //logger.info('displayName final value: ' + displayName.getValues().get(0)); | |
| } else if (sn != null && gn != null) { | |
| displayName.addValue(new valueType(gn + ' ' + surname)); | |
| //logger.info('displayName final value: ' + displayName.getValues().get(0)); | |
| } else if (sn != null) { | |
| displayName.addValue(new valueType(surname)); | |
| //logger.info('displayName final value: ' + displayName.getValues().get(0)); | |
| } else if (gn != null) { | |
| displayName.addValue(new valueType(gn)); | |
| //logger.info('displayName final value: ' + displayName.getValues().get(0)); | |
| } | |
| } else { | |
| //logger.info('displayName had value: ' + displayName.getValues().get(0)); | |
| } | |
| ]]> | |
| </Script> | |
| </AttributeDefinition> | |
| <!-- ========================================== --> | |
| <!-- Data Connectors --> | |
| <!-- ========================================== --> | |
| <!-- Data Connector for LDAP --> | |
| <DataConnector id="myLDAP" xsi:type="LDAPDirectory" | |
| ldapURL="%{idp.attribute.resolver.LDAP.ldapURL}" | |
| baseDN="%{idp.attribute.resolver.LDAP.baseDN}" | |
| principal="%{idp.attribute.resolver.LDAP.bindDN}" | |
| principalCredential="%{idp.attribute.resolver.LDAP.bindDNCredential}" | |
| connectTimeout="%{idp.attribute.resolver.LDAP.connectTimeout}" | |
| responseTimeout="%{idp.attribute.resolver.LDAP.responseTimeout}" | |
| trustFile="%{idp.attribute.resolver.LDAP.trustCertificates}" | |
| useStartTLS="%{idp.attribute.resolver.LDAP.useStartTLS:true}" | |
| connectionStrategy="%{idp.attribute.resolver.LDAP.connectionStrategy}" | |
| noResultIsError="true" | |
| multipleResultsIsError="true" | |
| exportAttributes="%{idp.attribute.resolver.LDAP.exportAttributes}"> | |
| <FilterTemplate> | |
| <![CDATA[ | |
| %{idp.attribute.resolver.LDAP.searchFilter} | |
| ]]> | |
| </FilterTemplate> | |
| <ConnectionPool | |
| minPoolSize="%{idp.pool.LDAP.minSize:3}" | |
| maxPoolSize="%{idp.pool.LDAP.maxSize:10}" | |
| blockWaitTime="%{idp.pool.LDAP.blockWaitTime:PT3S}" | |
| validatePeriodically="%{idp.pool.LDAP.validatePeriodically:true}" | |
| validateTimerPeriod="%{idp.pool.LDAP.validatePeriod:PT5M}" | |
| validateDN="%{idp.pool.LDAP.validateDN:}" | |
| validateFilter="%{idp.pool.LDAP.validateFilter:(objectClass=*)}" | |
| expirationTime="%{idp.pool.LDAP.idleTime:PT10M}"/> | |
| </DataConnector> | |
| <!-- Data Connector for eduPersonTargetedID - Computed Mode --> | |
| <DataConnector id="myComputedId" xsi:type="ComputedId" | |
| generatedAttributeID="computedID" | |
| salt="%{idp.persistentId.salt}" | |
| algorithm="%{idp.persistentId.algorithm:SHA}" | |
| encoding="%{idp.persistentId.encoding:BASE32}"> | |
| <InputDataConnector ref="myLDAP" attributeNames="%{idp.persistentId.sourceAttribute}" /> | |
| </DataConnector> | |
| <DataConnector id="staticAttributes" xsi:type="Static"> | |
| <Attribute id="schacHomeOrganizationType"> | |
| <Value>urn:schac:homeOrganizationType:eu:higherEducationalInstitution</Value> | |
| </Attribute> | |
| </DataConnector> | |
| </AttributeResolver> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment