Zur Persistent ID allgemein siehe unter Storage und Persistent Identifier.
Beispiel der Hochschule Bremen zur Generierung des Quellattributes zur persistentId mithilfe von „uid“ und „uidNumber“:
<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>
Sofern Sie die persistendId nicht pauschal an alle SPs weitergeben wollen, kann dies in einem RelyingPartyOverride definiert werden.
Dazu muss Folgendes gemacht werden:
<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>
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:
<!-- ... --> <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> <!-- ... -->
<!-- ... --> <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.
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.
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.
/opt/shibboleth-idp/conf/saml-nameid.properties
wird die Eigenschaft idp.persistentId.sourceAttribute = eduPersonUniqueId
gesetzt.localid
in der Tabelle shibpid
müssen auf die jeweiligen Werte des Attributs eduPersonUniqueId
abgeändert werden. Ich habe mir für die ganze Aktion ein Shellskript geschrieben.shibpid
.principalname
in der Tabelle shibpid
referenziert den Benutzernamen (uid
). Über diesen sucht man nun im LDAP-Server nach der jeweiligen eduPersonUniqueId
und setzt in der Spalte localid
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";""
shibpid
.
Ü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.