Versionen im Vergleich

Schlüssel

  • Diese Zeile wurde hinzugefügt.
  • Diese Zeile wurde entfernt.
  • Formatierung wurde geändert.
Kommentar: v4, probably

Funktionales Beispiel einer Konfiguration für den Shibboleth 3.x IDP und Java Scripting Engine "Nashorn", um das gewünschte USI Wien-eduPersonEntitlement zu berechnen, mit dem Studierende unter 25 Jahre ohne zusätzliche Umstände vergünstigte Tarife bei Kursen des USI Wien in Anspruch nehmen können. Dieses etwas komplexe Vorgehen verhindert, das Alter oder Geburtsdatum von Personen direkt an den Service Provider zu schicken. Gleichzeitig dient es als Beispiel für die Erzeugung bzw. komplexere Manipulation von Attributen im Shibboleth IDP.

...

Zur Berechnung des aktuellen Alters einer Person wird zuerst einmal das Geburtsdatum einer Person benötigt. Hat man dafür noch kein eigenes Attribut im LDAP-Verzeichnisdienst vorgesehen, bietet sich schacDateOfBirth aus dem SCHAC-Schema an. Dazu muß das Schema dem LDAP DSA bekannt gemacht, sowie allen (Benutzer-)Objekten, die einen schacDateOfBirth-Wert beinhalten können, die "auxiliary objectClass" schacPersonalCharacteristics zugewiesen werden. Wie im SCHAC-Schema angegeben, wird das Datum im Format JJJJMMTT gespeichert. Der 31. Dezember 1970 etwa würde so zu 19701231.

IDP-Konfiguration

attribute-resolver.xml

Um aus dem Geburtsdatum im IDP das Alter zu errechnen, braucht es etwas eigenen Code, über eine ScriptedAttribute-Definition des Shiboleth IDP. Damit wird die Integration von interpretierten Programmiersprachen wie ECMAScript/JavaScript (oder auch Jython) mit den Java-Objekten des IDP möglich, ohne Erweitungen für den IDP in Java programmieren zu müssen.

...

Codeblock
languagehtml/xml
titleeduPersonEntitlements per Script erzeugen (Java8/Nashorn)
<AttributeDefinition id="eduPersonEntitlement" xsi:type="ScriptedAttribute" >
    <InputDataConnector ref="myLDAP" attributeNames="schacDateOfBirth eduPersonEntitlement" />
    <InputAttributeDefinition ref="mappedEntitlements" />
    <AttributeEncoder xsi:type="SAML1String" name="urn:mace:dir:attribute-def:eduPersonEntitlement" encodeType="false" />
    <AttributeEncoder xsi:type="SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.7" friendlyName="eduPersonEntitlement" encodeType="false" />
    <Script><![CDATA[
var logger = Java.type("org.slf4j.LoggerFactory").getLogger("net.shibboleth.idp.attribute.resolver.script.usidiscount");
if (typeof mappedEntitlements != "undefined" && mappedEntitlements.getValues().size() > 0) {
  for ( i = 0; i < mappedEntitlements.getValues().size(); i++ ){
    eduPersonEntitlement.addValue(mappedEntitlements.getValues().get(i));
  }
  logger.trace("eduPersonEntitlement has values " + eduPersonEntitlement.getValues());
}
if (typeof schacDateOfBirth == "undefined" || schacDateOfBirth.getValues().size() < 1) {
  logger.debug("no schacDateOfBirth, ignoring");
} else {
  var dob = schacDateOfBirth.getValues().get(0);
  logger.trace("schacDateOfBirth is " + dob);
  var LocalDate  = Java.type("java.time.LocalDate");
  dob   = LocalDate.of(dob.slice(0,4), dob.slice(4,6), dob.slice(6,8));
  logger.trace("parsed dob is " + dob);
  var age = Java.type("java.time.Period").between(dob, LocalDate.now()).getYears();
  logger.trace("age is " + age);
  if (age < 25) {
    logger.debug("age is within USI limits, adding USI-entitlement");
    logger.trace("eduPersonEntitlement had values " + eduPersonEntitlement.getValues());
    eduPersonEntitlement.addValue("http://usi.at/student-discount");
    logger.trace("eduPersonEntitlement has values " + eduPersonEntitlement.getValues());
  } else {
    logger.debug("age is not within USI limits, doing nothing");
  }
}
logger.trace("eduPersonEntitlement final values: " + eduPersonEntitlement.getValues());
]]></Script>
</AttributeDefinition>
 
<!-- Beispiel fuer "mappedEntitlements" -->
<AttributeDefinition id="mappedEntitlements" xsi:type="Mapped" dependencyOnly="true">
    <InputAttributeDefinition ref="eduPersonAffiliation" />
    <ValueMap>
        <ReturnValue>urn:mace:dir:entitlement:common-lib-terms</ReturnValue>
        <SourceValue>member</SourceValue>
    </ValueMap>
    <ValueMap>
        <ReturnValue>urn:mace:terena.org:tcs:personal-user</ReturnValue>
        <SourceValue>member</SourceValue>
    </ValueMap>
</AttributeDefinition>

...

Stellt man das Loglevel für dieses spezifische Modul auf DEBUG (und wartet bis zu 5 Minuten, bis die logback.xml Konfiguration neu eingeladen wurde – oder man lädt diese manuell neu), schreibt der IDP in die Datei idp-prozess.log, ob die Werte vorhanden sind oder nicht, sowie ob aufgrund des Alters nun ein Entitlement erzeugt wurde oder nicht. Nur wenn man das Loglevel hier auf TRACE stellt, sind auch das zur Berechnung verwendete Geburtsdatum und die eduPersonEntitlement-Werte (vorher/nachher) selbst zu sehen. Ist man mit der IDP-Konfiguration zufrieden, kann das Loglevel für diesen logger zurück auf INFO gestellt werden, womit nach wenigen Minuten (oder nach erneutem Neuladen der logback-Konfiguration, jedenfalls ohne Neustart des IDP) keine weiteren Logzeilen für diesen logger geschrieben werden.

...