Sonderfälle bei Generierung und Weitergabe der Persistent ID
Zur Persistent ID allgemein siehe unter Storage und Persistent Identifier.
Generierung des Quellattributes mithilfe von zwei IdM-Attributen
Beispiel der Hochschule Bremen zur Generierung des Quellattributes zur persistentId mithilfe von „uid“ und „uidNumber“:
- attribute-resolver.xml
<AttributeDefinition xsi:type="ScriptedAttribute" id="uniqueIdentifier" > <InputAttributeDefinition ref="uid" /> <InputAttributeDefinition ref="uidNumber" /> <Script> <![CDATA[ uid= uid.getValues().get(0); uidNumber = uidNumber.getValues().get(0); stringUidNumber = String(uidNumber); newIdentifier = uid+stringUidNumber; uniqueIdentifier.getValues().add(newIdentifier); ]]> </Script> </AttributeDefinition>
Weitergabe der persistentId nur an bestimmte SPs
Sofern Sie die persistendId nicht pauschal an alle SPs weitergeben wollen, kann dies in einem RelyingPartyOverride definiert werden.
Dazu muss Folgendes gemacht werden:
- im Default-Block wird nur die TransientId freigegeben
- einen Override definieren, in dem für gewisse EntityIds die persistentId freigegeben wird
- relying-party.xml
<beans ...> <!-- ... --> <bean id="shibboleth.DefaultRelyingParty" parent="RelyingParty"> <property name="profileConfigurations"> <list> <bean parent="Shibboleth.SSO" p:postAuthenticationFlows="#{{'terms-of-use', 'attribute-release'}}" /> <!-- ... --> <bean parent="SAML2.SSO" p:postAuthenticationFlows="#{{'terms-of-use', 'attribute-release'}}" p:nameIDFormatPrecedence="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" /> <!-- ... --> </list> </property> </bean> <util:list id="shibboleth.RelyingPartyOverrides"> <!-- ... --> <!-- komma-separierte Liste der Entity IDs der berechtigten SPs, hier inkl. DFNConf --> <bean parent="RelyingPartyByName" c:relyingPartyIds="#{{'https://testsp3.aai.dfn.de/shibboleth', 'https://testsp2.aai.dfn.de/shibboleth', 'https://webconf.vc.dfn.de/shibboleth', 'https://my.conf.dfn.de/shibboleth', 'https://self.conf.dfn.de/shibboleth', 'https://www.conf.dfn.de/shibboleth'}}"> <property name="profileConfigurations"> <list> <bean parent="SAML2.SSO" p:postAuthenticationFlows="#{{'terms-of-use', 'attribute-release'}}" p:nameIDFormatPrecedence="#{{'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'}}" /> <ref bean="SAML2.Logout" /> <ref bean="SAML2.AttributeQuery" /> <ref bean="SAML2.ArtifactResolution" /> </list> </property> </bean> </util:list> </beans>
Freigabe in Abhängigkeit von anderen Attributen
Möchte man die Freigabe der persistentId analog zu Attribut-Filterregeln weiter einschränken, sind mehrere Schritte nötig.
Man kann zwar mit Hilfe von ActivationConditions die NameIDGeneration einschränken, jedoch existiert zu diesem Zeitpunkt noch kein AttributContext. Man kann deshalb in der /conf/relying-party.xml
keine Abhängigkeit zu anderen Attributen abbilden: Diese werden erst nach dem Login der Nutzer*innen ausgelesen.
Um die persistentId dennoch nur dann an einen SP auszuliefern, wenn Nutzer*innen z.B. ein bestimmtes Entitlement haben, muss man wie folgt vorgehen:
- globale Freigabe der persistentID für den SP:
- /conf/relying-party.xml
<!-- ... --> <util:list id="shibboleth.RelyingPartyOverrides"> <bean parent="RelyingPartyByName" c:relyingPartyIds="#{{ 'https://e5.onthehub.com' }}"> <property name="profileConfigurations"> <list> <bean parent="SAML2.SSO" p:postAuthenticationFlows="attribute-release" p:nameIDFormatPrecedence="#{{'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'}}" /> <ref bean="SAML2.Logout" /> <ref bean="SAML2.AttributeQuery" /> <ref bean="SAML2.ArtifactResolution" /> </list> </property> </bean> <!-- ... -->
- Definition einer Condition mit allen Anforderungen an ein Attribut und Referenzierung als Abhängigkeit bei der Generierung der persistentID:
- /system/conf/saml-nameid-system.xml
<!-- ... --> <bean id="shibboleth.SAML2PersistentGenerator" lazy-init="true" class="net.shibboleth.idp.saml.nameid.impl.PersistentSAML2NameIDGenerator" p:useUnfilteredAttributes="%{idp.persistentId.useUnfilteredAttributes:true}" p:persistentIdGenerator-ref="#{'%{idp.persistentId.generator:shibboleth.ComputedPersistentIdGenerator}'.trim()}" p:activationCondition-ref="dreamspark"> <property name="attributeSourceIds"> <bean parent="shibboleth.CommaDelimStringArray" c:_0="#{'%{idp.persistentId.sourceAttribute:}'.trim()}" /> </property> </bean> <bean id="dreamspark" parent="shibboleth.Conditions.OR"> <constructor-arg> <list> <bean parent="shibboleth.Conditions.NOT"> <constructor-arg> <bean parent="shibboleth.Conditions.RelyingPartyId" c:_0="https://e5.onthehub.com" /> </constructor-arg> </bean> <bean class="net.shibboleth.idp.profile.logic.SimpleAttributePredicate" p:useUnfilteredAttributes="true"> <property name="attributeValueMap"> <map> <entry key="eduPersonEntitlement"> <list> <value>Dreamspark-Premium-User-Wirtschaft</value> <value>Dreamspark-Premium-User-Informatik</value> </list> </entry> </map> </property> </bean> </list> </constructor-arg> </bean> <!-- ... -->
Dadurch ist folgendes Verhalten des IdP konfiguriert: Wenn es sich um den konfigurierten SP handelt und die Nutzer*innen keinen der oben genannten Attribut-Werte aufweisen, dann schlägt die Condition fehl: Es wird keine persistentID generiert. In allen anderen Fällen sollte die Generierung der persistentID problemlos funktionieren.
Beispiel für den Wechsel des IdM-Quellattributs
Das Beispiel der Uni Jena zeigt, wie bei Bedarf das IdM-Quellattribut gewechselt werden kann, aus dem persistentIDs generiert werden, und wie dabei schon bestehende persistentIds erhalten bleiben.
Migration der persistentId-DB an der Uni Jena
Ziel der Aktion war das Auswechseln des Quellattributs der persistentId (gespeichert in
einer PostgreSQL-Datenbank), die doch nicht so unique uid
sollte hierbei durch die
eduPersonUniqueId
ersetzt werden. Die eduPersonUniqueId
bilden wir im IDM aus einer UUID
ohne Bindestriche mit Scope hinten dran (Beispiel:
0c845b14f1c643ccac9de204632512cd@uni-xy.de
) und stellen sie per LDAP-Server zur Verfügung.
Der Shibboleth IdP war Version 3.2.1.
- Den IdP stoppen.
- In
/opt/shibboleth-idp/conf/saml-nameid.properties
wird die Eigenschaftidp.persistentId.sourceAttribute = eduPersonUniqueId
gesetzt. - Die Werte der Spalte
localid
in der Tabelleshibpid
müssen auf die jeweiligen Werte des AttributseduPersonUniqueId
abgeändert werden. Ich habe mir für die ganze Aktion ein Shellskript geschrieben.- Man erzeugt sich einen Dump der Tabelle
shibpid
. - Man arbeitet sich zeilenweise durch diesen Dump. Die Spalte
principalname
in der Tabelleshibpid
referenziert den Benutzernamen (uid
). Über diesen sucht man nun im LDAP-Server nach der jeweiligeneduPersonUniqueId
und setzt in der Spaltelocalid
deren Wert anstelle des bisherigen ein. Beispiel:# Aus... "https://idp.uni-xy.de/idp/shibboleth";"https://testsp2.aai.dfn.de/shibboleth";"aaidemo";"aaidemo";"Znc0wfn/YabcZe7neb73Es123456";"";"2014-08-12 14:10:47.29";"" # ...wird so... "https://idp.uni-xy.de/idp/shibboleth";"https://testsp2.aai.dfn.de/shibboleth";"aaidemo";"0e2cba36852b44d8be29e4168ec71e0d@uni-xy.de";"Znc0wfn/YabcZe7neb73Es123456";"";"2014-08-12 14:10:47.29";""
- Man kopiert den modifizierten Dump zurück in die Tabelle
shibpid
.
- Den IdP wieder starten und überprüfen, ob die Sache funktioniert hat.
Übrig bleibt nun noch das Entfernen der uid
als Bestandteil der Bildungsvorschriften anderer Attribute, z.B. beim eduPersonPrincipalName
(= uid + „@uni-xy.de“). An den Bestandsnutzern kann man da nichts machen, der Plan ist aber, für neue Benutzer auch hier eduPersonPrincipalName = eduPersonUniqueId auszuliefern. Das sollte dann für eine ausreichende Kollisionsfreiheit sorgen.