Shibboleth IdPv4 in der Schulungs-VM

DFN Logo






Hinweise

  1. Sie können den Shibboleth Identity Provider mit dieser Anleitung in der VM installieren. Die weiterführenden Links zur Dokumentation sind für Ihre spätere, echte Installation gedacht.
  2. Import des heruntergeladenen .ova-Images in Virtualbox: Datei -> Appliance importieren. Im BIOS muss Hardware-Virtualisierung angeschaltet sein.
  3. Für ein Copy & Paste ohne Gasterweiterungen können Sie diese Installationsanleitung selbstverständlich auch im Browser in der VM abrufen. Dazu finden Sie im Firefox ein Lesezeichen in der Leiste.
  4. Betriebssystem der Schulungs-VM: Debian 12
  5. Die Nutzerkennung lautet "shibboleth". Alle Passwörter lauten ebenfalls "shibboleth".
  6. Auf der VM befindet sich ein LDAP-Browser (phpLDAPadmin), der im Web-Browser (Firefox) als Lesezeichen gesetzt ist. Im Verzeichnis finden Sie vier Test-Accounts mit verschiedenen Attributen.
  7. Zum besseren Verständnis des lokalen Setups (idp/sp1/sp2) hilft ein Blick in /etc/hosts und die Apache-Konfiguration unter /etc/apache2/sites-enabled.
  8. Für die echte spätere Installation folgen Sie bitte der Anleitung im Wiki.
  9. Die wichtigsten vorinstallierten Pakete sind Web-, Datenbank- und LDAP-Server:
  10. Los geht's! Starten Sie die virtuelle Maschine in Virtualbox und melden Sie sich mit dem Passwort "shibboleth" an. Bitte arbeiten Sie möglichst präzise, um nachträgliche Fehlersuchen zu vermeiden. Achten Sie beim Bearbeiten von Konfigurationsdateien auf die Syntax (häufig xml).

JAVA vorbereiten

Erlangen Sie root-Rechte:
su -
Setzen Sie folgende Umgebungsvariablen:
# Datei: /etc/environment
JAVA_HOME="/usr/lib/jvm/java-17-openjdk-amd64/"
Laden Sie diese Umgebungsvariablen neu:
exit
su -

Vorbereitung der MySQL-Datenbank

zur Doku: Datenbank-Konfiguration

Nun legen Sie eine Datenbank für Shibboleth an. Sie wird zwei Tabellen enthalten:
  1. "StorageRecords" für die Speicherung von User Consent und Sessions
  2. "shibpid" für die Speicherung von persistentIDs
mariadb -uroot -pshibboleth
SET NAMES 'utf8';
SET CHARACTER SET utf8;
CHARSET utf8;
CREATE DATABASE IF NOT EXISTS shibboleth CHARACTER SET=utf8;
USE shibboleth;

CREATE TABLE IF NOT EXISTS StorageRecords (
    context varchar(255) NOT NULL,
    id varchar(255) NOT NULL,
    expires bigint(20) DEFAULT NULL,
    value longtext NOT NULL,
    version bigint(20) NOT NULL,
  PRIMARY KEY (context, id)
) COLLATE utf8_bin;
 
CREATE TABLE IF NOT EXISTS shibpid (
    localEntity VARCHAR(255) NOT NULL,
    peerEntity VARCHAR(255) NOT NULL,
    persistentId VARCHAR(50) NOT NULL,
    principalName VARCHAR(50) NOT NULL,
    localId VARCHAR(50) NOT NULL,
    peerProvidedId VARCHAR(50) NULL,
    creationDate TIMESTAMP NOT NULL,
    deactivationDate TIMESTAMP NULL,
    PRIMARY KEY (localEntity, peerEntity, persistentId)
);
 
CREATE USER 'shibboleth'@'localhost' IDENTIFIED BY 'shibboleth'; 
GRANT ALL PRIVILEGES ON shibboleth.* TO 'shibboleth'@'localhost';
FLUSH PRIVILEGES;
exit;

Shibboleth-Installation

Sie installieren in diesem Tutorial die Version 4.2.1. Im Verlauf des Workshop werden Sie ein Update auf die aktuelle Version 4.3.1 durchführen. Laden Sie sich die 4.2.1 als tar-Archiv in das Verzeichnis /opt/install herunter. Die Dateien finden Sie im Download-Verzeichnis von Shibboleth.
wget -P /opt/install https://shibboleth.net/downloads/identity-provider/archive/4.2.1/shibboleth-identity-provider-4.2.1.tar.gz
wget -P /opt/install https://shibboleth.net/downloads/identity-provider/archive/4.2.1/shibboleth-identity-provider-4.2.1.tar.gz.sha256
wget -P /opt/install https://shibboleth.net/downloads/identity-provider/archive/4.2.1/shibboleth-identity-provider-4.2.1.tar.gz.asc
wget -P /opt/install https://shibboleth.net/downloads/PGP_KEYS
gpg --import /opt/install/PGP_KEYS
gpg --verify /opt/install/shibboleth-identity-provider-4.2.1.tar.gz.asc /opt/install/shibboleth-identity-provider-4.2.1.tar.gz
cd /opt/install && sha256sum -c shibboleth-identity-provider-4.2.1.tar.gz.sha256
tar -xzf /opt/install/shibboleth-identity-provider-4.2.1.tar.gz -C /opt/install/
Führen Sie das interaktive Installerskript aus:
/opt/install/shibboleth-identity-provider-4.2.1/bin/install.sh
Achtung, bei "Hostname" müssen Sie die Standardvorgabe von 10.0.2.15 zu idp.local ändern. Bei den abgefragten Passwörtern können Sie zu Testzwecken "shibboleth" eingeben. Bei den anderen Feldern können Sie einfach mit der ENTER-Taste bestätigen.
Source (Distribution) Directory (press  to accept default): [/opt/install/shibboleth-identity-provider-4.2.1] ? 
Installation Directory: [/opt/shibboleth-idp] ? 
Host Name: [10.0.2.15] ? idp.local
### im Folgenden setzen Sie Passwörter, zu Testzwecken z.B. "shibboleth"
Backchannel PKCS12 Password:
Re-enter password: 
Cookie Encryption Key Password:
Re-enter password: 
SAML EntityID: [https://idp.local/idp/shibboleth] ? 
Attribute Scope: [local] ? 

Shibboleth-Konfiguration

Metadaten

zur Doku: Metadaten-Konfiguration

In diesem Schritt machen Sie dem neuen IdP die beiden Service Provider bekannt, die in der VM bereits konfiguriert sind. Laden Sie die lokalen Metadaten der beiden SPs in das entsprechende Verzeichnis des IdP. In einer Produktivinstanz würden Sie hier stattdessen die Föderationsmetadaten einbinden. (Den Zertifikatscheck überspringen Sie hier nur wegen der lokalen Domain bzw. des selbst signierten Zertifikates in der VM.)
wget --no-check-certificate https://sp1.local/Shibboleth.sso/Metadata -O /opt/shibboleth-idp/metadata/sp1-metadata.xml
wget --no-check-certificate https://sp2.local/Shibboleth.sso/Metadata -O /opt/shibboleth-idp/metadata/sp2-metadata.xml
Konfigurieren Sie diese Metadatensätze im IdP: Die beiden Zeilen gehören vor das schließende MetadataProvider-Tag in der Datei. Ja: Die Datei hat dann ein MetadataProvider-Tag im MetadataProvider-Tag.
<!-- Datei: /opt/shibboleth-idp/conf/metadata-providers.xml -->
    <MetadataProvider id="SP1-Metadata"  xsi:type="FilesystemMetadataProvider" metadataFile="/opt/shibboleth-idp/metadata/sp1-metadata.xml"/>
    <MetadataProvider id="SP2-Metadata"  xsi:type="FilesystemMetadataProvider" metadataFile="/opt/shibboleth-idp/metadata/sp2-metadata.xml"/>
Bei der Installation wurde eine Datei mit den IdP-Metadaten automatisch erstellt. In der VM verwenden wir sie, um den lokalen SPs die IdP-Metadaten bekannt zu machen. (Im Produktivbetrieb werden stattdessen die Föderationsmetadaten verwendet.) Diese Datei /opt/shibboleth-idp/metadata/idp-metadata.xml muss an zwei Stellen angepasst werden:
  1. Die Datei enthält ein Ablaufdatum, das entfernt werden muss. Löschen Sie den String, z.B. validUntil="2022-01-17T09:59:23.071Z".
    <!-- Datei: /opt/shibboleth-idp/metadata/idp-metadata.xml -->
    <EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" 
        xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui"
        xmlns:req-attr="urn:oasis:names:tc:SAML:protocol:ext:req-attr" entityID="https://idp.local/idp/shibboleth">
          
  2. Weiter unten sehen Sie in den Zeilen 123-128 auskommentierte Endpunkte für Single Logout (SSO). Damit Single Logout in der VM funktioniert, entfernen Sie die Kommentarzeichen um die Zeilen 123-128. Sie müssen sowohl das den Kommentar einleitende "<!--" als auch das schließende "-->" entfernen.
    
    <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://idp.local/idp/profile/SAML2/POST/SLO"/>
    <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://idp.local/idp/profile/SAML2/POST-SimpleSign/SLO"/>
    <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp.local/idp/profile/SAML2/Redirect/SLO"/>
    <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://idp.local:8443/idp/profile/SAML2/SOAP/SLO"/>
          

LDAP-Anbindung

zur Doku: LDAP-/AD-Anbindung

Konfigurieren Sie die Anbindung an den vorinstallierten LDAP-Server in der Schulungs-VM. Tipp für die Praxis: Der bind-Account sollte nur Leserechte haben! In einem realen Setup werden Sie sich - anders als innerhalb der Schulungs-VM - verschlüsselt mit dem LDAP-/AD-Server verbinden. Folgende Zeilen müssen editiert werden, der Rest bleibt so, wie er ist:
# Datei: /opt/shibboleth-idp/conf/ldap.properties
idp.authn.LDAP.authenticator                   = bindSearchAuthenticator
idp.authn.LDAP.ldapURL                         = ldap://idp.local:389
idp.authn.LDAP.useStartTLS                     = false
# idp.authn.LDAP.trustCertificates                = %{idp.home}/credentials/ldap-server.crt
idp.authn.LDAP.baseDN                          = dc=users,dc=nodomain
idp.authn.LDAP.bindDN                          = cn=admin,dc=nodomain
Das Bind-Passwort wird - zusammen mit anderen Credentials - in einer separaten Datei abgelegt. Sie hat eingeschränkte Zugriffsrechte. Sie enthält auch die bei der Installation gesetzten Passwörter:
root@ubuntu:~# ls -la /opt/shibboleth-idp/credentials/secrets.properties
-rw------- 1 tomcat tomcat 588 Okt  8 16:08 /opt/shibboleth-idp/credentials/secrets.properties
Passen Sie das Muster-Passwort aus der mitgelieferten Datei an. Achtung: Es darf kein Leerzeichen am Ende des Passwortes stehen!
# Datei: /opt/shibboleth-idp/credentials/secrets.properties
idp.authn.LDAP.bindDNCredential                = shibboleth

Zugriff auf das Webinterface regeln

Erlauben Sie den Zugriff auf das Webinterface vom kompletten /8er-Netz auf localhost: Tragen Sie statt der allowedRange 127.0.0.1/32 die 127.0.0.0/8 ein.
<!-- Datei: /opt/shibboleth-idp/conf/access-control.xml -->
  <util:map id="shibboleth.AccessControlPolicies">
    <entry key="AccessByIPAddress">
      <bean parent="shibboleth.IPRangeAccessControl" p:allowedRanges="#{ {'127.0.0.0/8', '::1/128'} }" />
    </entry>
  </util:map>

Konfiguration des Attribute Resolver

zur Doku: Attribut-Konfiguration

Die zentrale Konfigurationsdatei für die Generierung von Attributen ist /opt/shibboleth-idp/conf/attribute-resolver.xml.

Hier definieren Sie, welche Attribute Ihre Shibboleth-Instanz kennt, aus welchen Quellen dafür Attribute geholt werden und ggf. wie sie im IdP umgebaut werden sollen. Laden Sie sich bitte zunächst unsere Beispieldatei ins conf-Verzeichnis herunter:
wget https://download.aai.dfn.de/ws/idp2023/idpv4-attribute-resolver.xml -O /opt/shibboleth-idp/conf/attribute-resolver.xml
Diese xml-Datei enthält u.a. Javascript-Code, der ausgeführt werden soll, damit bestimmte Attribute IdP-seitig generiert werden. Unter OpenJDK 17 benötigt der IdP dafür ein Plugin, das bei früheren Java-Versionen nicht nötig war. So installieren Sie das Nashorn-Plugin:
/opt/shibboleth-idp/bin/plugin.sh --truststore /opt/install/PGP_KEYS -I net.shibboleth.idp.plugin.nashorn

Attribut-Definitionen

Schauen Sie sich die Datei an: Im oberen Teil der Datei conf/attribute-resolver.xml finden Sie den Abschnitt "Attribute Definitions" mit den Attributen, die der IdP kennen soll. In diesem Beispiel-Ausschnitt steht sinngemäß: "Ich definiere für den IdP ein Attribut organizationalUnit. Um es zu befüllen, hole ich aus dem Data Connector myLDAP das dortige Attribut ou."
<!-- Datei: /opt/shibboleth-idp/conf/attribute-resolver.xml -->
    <AttributeDefinition xsi:type="Simple" id="organizationalUnit">
        <InputDataConnector ref="myLDAP" attributeNames="ou"/>
    </AttributeDefinition>

Data Connectors

Im unteren Teil der conf/attribute-resolver.xml finden Sie den Abschnitt "DataConnectors", also die Datenquellen für die zu generierenden Attribute. Sie sehen dort drei aktive Konnektoren:
  1. einen LDAP-Connector,
  2. einen Connector mit statisch definierten Attributen, hier z.B. mit dem hartkodierten Namen der Hochschule
  3. einen Connector für die MySQL-Datenbank (mit den persistentIDs)
Beispielauszug:
<!-- Datei: /opt/shibboleth-idp/conf/attribute-resolver.xml -->
    <DataConnector id="staticAttributes" xsi:type="Static">
        <Attribute id="o">
            <Value>Beispiel-Hochschule</Value>
        </Attribute>
    </DataConnector>
Bitte beachten Sie im Data Connector "myLDAP" die Zeile "exportAttributes". Ab Shibboleth IdP 4.x können Sie so Attribute aus dem Identity Management direkt verwenden, wenn sie im IdM genau so heißen, wie in der IdP-internen Attribute Registry (dazu später mehr). Diese Attribute müssen nicht mehr als einzelne AttributeDefinitions oben aufgelistet werden.
opt/shibboleth-idp/conf/attribute-resolver.xml -->
        <DataConnector id="myLDAP" xsi:type="LDAPDirectory"
        ...
        exportAttributes="uid givenName sn mail displayName">
        ...
    </DataConnector>

Transcoding-Regeln

Zu allen definierten Attributen sind zusätzliche Informationen in der Attribute Registry hinterlegt. Sie ist im Unterordner /opt/shibboleth-idp/conf/attributes und wurde u.a. eingeführt, um die Datei conf/attribute-resolver.xml zu vereinfachen. Die Informationen in der Attribute Registry müssen Sie v.a. beim initialen Aufsetzen des IdP kennen und ggf. anpassen. In dem Ordner liegt für jedes Attributschema eine Datei. Schauen Sie sich die Datei /opt/shibboleth-idp/conf/attributes/inetOrgPerson.xml an. Für jedes Attribut aus dem inetOrgPerson-Schema ist hier das Standard-Set an Properties hinterlegt. Dieser Ausschnitt zeigt die Einstellungen für das mail-Attribut:
  1. Das mail-Attribut kann in SAML1 und SAML2 übergeben werden. SAML1 ist veraltet und in der DFN-AAI nicht mehr erforderlich. Sie können die Zeile <prop key="saml1.name">urn:mace:dir:attribute-def:mail</prop> daher auch getrost entfernen.
  2. Das mail-Attribut wird - wie der Spezifikation vorgesehen - in SAML2 als urn:oid:0.9.2342.19200300.100.1.3 übergeben. Dies ist die Information, die SPs für die Zuordnung der Attribute benötigen.
  3. Das mail-Attribut hat hier einen Anzeigenamen und eine Kurzbeschreibung in deutsch und englisch. Die Nutzer*innen bekommen dies zu sehen, wenn sie nach der Zustimmung zur Attributfreigabe gefragt werden.
<!-- Datei: /opt/shibboleth-idp/conf/attributes/inetOrgPerson.xml (gekürzt!) -->
        <bean parent="shibboleth.TranscodingProperties">
            <property name="properties">
                <props merge="true">
                    <prop key="id">mail</prop>
                    <prop key="transcoder">SAML2StringTranscoder SAML1StringTranscoder</prop>
                    <prop key="saml2.name">urn:oid:0.9.2342.19200300.100.1.3</prop>
                    <prop key="saml1.name">urn:mace:dir:attribute-def:mail</prop>
                    <prop key="displayName.en">E-mail</prop>
                    <prop key="displayName.de">E-Mail</prop>
                    <prop key="description.en">E-Mail: Preferred address for e-mail to be sent to this person</prop>
                    <prop key="description.de">E-Mail-Adresse</prop>
                </props>
            </property>
        </bean>
Jedes Attribut, das im Attribute Resolver verwendet wird - in einer Attribute Definition oder über exportAttributes - muss dem IdP über die Registry bekannt sein (dazu später mehr).

Konfiguration von SAML2-NameIDs

Der IdP soll zusätzlich zu den Attributen in ./conf/attribute-resolver.xml zwei Arten von SAML2-NameIDs unterstützen:
  1. persistentIDs werden pro Useraccount und pro SP nach einem konfigurierbaren Schema generiert. Sie bleiben dann gleich, das heißt, SPs können anhand dieser Pseudonyme Accounts personalisieren, ohne Realnamen zu kennen. (Es sei denn, die werden auch übermittelt.)
  2. transientIDs werden auch pro Useraccount und pro SP generiert. Sie ändern sich aber bei jedem Login.

Um die SAML Name IDs verwenden zu können, sind etliche Konfigurationsschritte an verschiedenen Stellen nötig. (Die jeweilige Datei ist den Schnipseln als Kommentar beigefügt.) Der MySQL-Datenbank-Connector ist - wie eben gesehen - bereits in unserer Beispielkonfiguration in conf/attribute-resolver.xml enthalten.

Ihre persistentIDs sollen aus dem Quellattribut uid mit einem Hash erstellt und in der MariaDB-Datenbank gespeichert bzw. aus ihr geholt werden. Dies stellen Sie in /opt/shibboleth-idp/conf/saml-nameid.properties ein. Behalten Sie die bereits bestehende Konfiguration und ändern bzw. aktivieren Sie nur folgende Zeilen:
# Datei: /opt/shibboleth-idp/conf/saml-nameid.properties
idp.persistentId.sourceAttribute = uid
idp.persistentId.generator = shibboleth.StoredPersistentIdGenerator
idp.persistentId.dataSource = shibboleth.MySQLDataSource
Der Hash wird aus Sicherheitsgründen in der zugriffsbeschränkten Passwortdatei abgelegt. In einer produktiven Installation sollte dieser Salt-Hash möglichst beliebig, also zufällig generiert, und lang sein und mit niemandem geteilt werden.
# Datei: /opt/shibboleth-idp/credentials/secrets.properties
idp.persistentId.salt = my-very-very-long-hash
In der Datei /opt/shibboleth-idp/conf/saml-nameid.xml schalten Sie die Generierung der persistentIDs an: Entfernen Sie die Kommentarzeichen in den Zeilen 37 und 39, also vor und nach der Zeile mit "shibboleth.SAML2PersistentGenerator".
<!-- Datei /opt/shibboleth-idp/conf/saml-nameid.xml -->
        <!-- Uncommenting this bean requires configuration in saml-nameid.properties. -->
        <ref bean="shibboleth.SAML2PersistentGenerator" />
Gleich geschafft. Jetzt aktivieren Sie noch die Verarbeitung der persistentIDs, indem Sie in der Datei /opt/shibboleth-idp/conf/c14n/subject-c14n.xmlfolgende Zeile aktivieren, indem Sie die Kommentarzeichen am Anfang und am Ende der Zeile 110 entfernen:
<!-- Datei: /opt/shibboleth-idp/conf/c14n/subject-c14n.xml -->
<ref bean="c14n/SAML2Persistent" />

Konfiguration der Datenbank-Anbindung

Die Datenbank selbst haben Sie oben ja bereits angelegt. Der Shibboleth greift neuerdings (und ab der kommenden IdP-Version 5.x zwingend) über ein Plugin auf die Datenbank zu. Dieses JDBC-Plugin installieren Sie so:
/opt/shibboleth-idp/bin/plugin.sh --truststore /opt/install/PGP_KEYS -I net.shibboleth.plugin.storage.jdbc
Fügen Sie dann für die MariaDB-Konfiguration folgende Zeilen zur Datei conf/global.xml hinzu, z.B. ganz unten vor das schließende </beans>-Tag:
<!-- Datei /opt/shibboleth-idp/conf/global.xml -->
        <bean id="shibboleth.MySQLDataSource"
              class="%{mysql.class}"
              p:driverClassName="org.mariadb.jdbc.Driver"
              p:url="%{mysql.url}"
              p:username="%{mysql.username}"
              p:password="%{mysql.password}"
              p:maxWait="15000"
              p:testOnBorrow="true"
              p:maxActive="100"
              p:maxIdle="100"
              p:validationQuery="select 1"
              p:validationQueryTimeout="5" />

        <bean id="JDBCStorageService"
              parent="shibboleth.JDBCStorageService"
              p:cleanupInterval="%{idp.storage.cleanupInterval:PT10M}"
              p:dataSource-ref="shibboleth.MySQLDataSource" />
Speichern Sie die Datenbank-Credentials, indem Sie diese Zeilen an die conf/idp.properties anhängen:
# Datei /opt/shibboleth-idp/conf/idp.properties
mysql.class    = org.apache.tomcat.jdbc.pool.DataSource
mysql.url      = jdbc:mysql://localhost:3306/shibboleth
mysql.username = shibboleth
An derselben Stelle geben Sie an, dass Sie die Sessions und den User Consent in der MySQL-Datenbank speichern möchten:
# Datei /opt/shibboleth-idp/conf/idp.properties
idp.session.StorageService = JDBCStorageService
idp.consent.StorageService = JDBCStorageService
idp.consent.attribute-release.userStorageKey = shibboleth.consent.PrincipalConsentStorageKey
idp.consent.attribute-release.userStorageKeyAttribute = %{idp.persistentId.sourceAttribute}
idp.consent.terms-of-use.userStorageKey = shibboleth.consent.PrincipalConsentStorageKey
idp.consent.terms-of-use.userStorageKeyAttribute = %{idp.persistentId.sourceAttribute}
idp.consent.allowGlobal = false
idp.consent.compareValues = true
Fehlt nur noch das Datenbank-Passwort des Datenbank-Users "shibboleth". Es gehört ebenfalls in die credentials/secrets.properties:
# Datei: /opt/shibboleth-idp/credentials/secrets.properties
mysql.password = shibboleth

Konfiguration von Attributfreigaben für die beiden lokalen Service Provider

Die zentrale Konfigurationsdatei für Attributfreigaben: /opt/shibboleth-idp/conf/attribute-filter.xml

Geben Sie einige Attribute für die beiden lokalen Service Provider in der Schulungs-VM frei. Dazu fügen Sie einen der folgenden Schnipsel zwischen die AttributeFilterPolicyGroup-Tags ein. Beide Schreibweisen sind möglich.
<!-- Datei: /opt/shibboleth-idp/conf/attribute-filter.xml -->
    <!-- Release to local SPs (1. Schreibweise) -->
    <AttributeFilterPolicy id="SPs_locals">
        <PolicyRequirementRule xsi:type="OR">
            <Rule xsi:type="Requester" value="https://sp1.local/shibboleth" />
            <Rule xsi:type="Requester" value="https://sp2.local/shibboleth" />
        </PolicyRequirementRule>
        <AttributeRule attributeID="eduPersonScopedAffiliation" permitAny="true" />
        <AttributeRule attributeID="surname"                    permitAny="true" />
        <AttributeRule attributeID="givenName"                  permitAny="true" />
        <AttributeRule attributeID="mail"                       permitAny="true" />
        <AttributeRule attributeID="uid"                        permitAny="true" />
    </AttributeFilterPolicy>
<!-- Datei: /opt/shibboleth-idp/conf/attribute-filter.xml -->
    <!-- Release to local SPs (2. Schreibweise) -->
    <AttributeFilterPolicy id="SPs_locals">
        <PolicyRequirementRule xsi:type="OR">
            <Rule xsi:type="Requester" value="https://sp1.local/shibboleth" />
            <Rule xsi:type="Requester" value="https://sp2.local/shibboleth" />
        </PolicyRequirementRule>
        <AttributeRule attributeID="eduPersonScopedAffiliation">
            <PermitValueRule xsi:type="ANY" />
        </AttributeRule>
        <AttributeRule attributeID="surname">
            <PermitValueRule xsi:type="ANY" />
        </AttributeRule>
        <AttributeRule attributeID="givenName">
            <PermitValueRule xsi:type="ANY" />
        </AttributeRule>
        <AttributeRule attributeID="mail">
            <PermitValueRule xsi:type="ANY" />
        </AttributeRule>
        <AttributeRule attributeID="uid">
            <PermitValueRule xsi:type="ANY" />
        </AttributeRule>
    </AttributeFilterPolicy>

Anpassung von Dateirechten

Stellen Sie sicher, dass der Tomcat-Benutzeraccount das Installationsverzeichnis besitzt. Bei Tomcat 9 heißt der Tomcat-User nur noch tomcat (ohne Versionsnummer).
# chown -R tomcat:tomcat /opt/shibboleth-idp/

Neustart von Diensten

Beobachten Sie in einem Terminal das Tomcat-Log und starten Sie in einem anderen den Tomcat neu:
# tail -f /var/log/tomcat9/catalina.DATUM.log
# systemctl restart tomcat9.service
In der Schulungs-VM müssen Sie auch den lokalen Shibboleth-SP hier einmal neustarten, weil er die neu hinzugekommenen IdP-Metadaten einlesen muss. shibd ist der SP, nicht der IdP!
# systemctl restart shibd.service

Prüfung des IdP-Status

Versuchen Sie, die Statusseite des IdP zu erreichen: https://idp.local/idp/status. Ggf. müssen Sie die selbstsignierten Zertifikate des Webservers im Browser durchwinken.

Auf der Statusseite sehen Sie u.a. die installierten Plugins und die aktivierten Module. Prüfen Sie dennoch auch auf der Kommandozeile, ob die beiden Plugins (JDBC und Nashorn) installiert sind, und welche Module bei einer Standardinstallation aktiviert sind:
# /opt/shibboleth-idp/bin/plugin.sh -l
# /opt/shibboleth-idp/bin/module.sh -l
Wenn Ihr IdP noch nicht erreichbar ist, können Sie sich schon selbst auf die Fehlersuche begeben. Die relevanten Logdateien: In unserem Wiki finden Sie außerdem ein paar Hinweise zum Troubleshooting.

Erstes Login für SP1

Wenn Sie eine funktionierende Statusseite haben, können Sie versuchen, sich am SP1 anzumelden. Besuchen Sie im Firefox in der VM den SP1 (Lesezeichenliste). Sie sollten zum IdP umgeleitet werden. Dort melden Sie sich mit folgenden Zugangsdaten an:
username: professorin
password: shibboleth
Bei Erfolg: Auf dem SP1 sollten Sie jetzt eine phpinfo-Seite sehen, auf der oben steht, dass dies der SP1 ist. "SP2" ist noch geschützt und kann so nicht benutzt werden.

Untersuchung der Installation

Metadatensätze:
ls /opt/shibboleth-idp/metadata/
less /opt/shibboleth-idp/metadata/idp-metadata.xml
less /opt/shibboleth-idp/metadata/sp1-metadata.xml
Datenbank:
mysql
use shibboleth;
select * from StorageRecords\G;
select * from shibpid\G;
exit;

Tipps und Tricks

Neuladen des Shibboleth-IdP

Es gibt verschiedene Wege, eine Shibboleth-Instanz neu zu laden: Sie können Tomcat das Servlet neu laden lassen. Für Tests ist das ein guter, schneller Weg, im Produktivbetrieb würde es jedoch eine kurze Störung des Betriebs geben.
# touch /opt/shibboleth-idp/war/idp.war
Sie können das war file neu bauen lassen. Dies ist nötig, wenn Sie im Ordner edit-webapp Veränderungen vorgenommen haben.
# /opt/shibboleth-idp/bin/build.sh
Sie können die Intervalle für automatisches Neuladen der Konfiguration anpassen. Standardwerte:
# Datei: /opt/shibboleth-idp/conf/services.properties
# Beispiele:
idp.service.logging.checkInterval = PT5M
idp.service.relyingparty.checkInterval = PT15M
idp.service.attribute.resolver.checkInterval = PT15M
idp.service.attribute.filter.checkInterval = PT15M
Sie können so genannte Reload-URLs benutzen, um das Neuladen der Konfiguration über eine URL zu triggern.

zur Doku: WebInterfaces

# Beispiele:
# attribute-resolver.xml neu laden
curl https://idp.local/idp/profile/admin/reload-service?id=shibboleth.AttributeResolverService
# attribute-filter.xml neu laden
curl https://idp.local/idp/profile/admin/reload-service?id=shibboleth.AttributeFilterService

Logging

zur Doku: Logging

Logfiles, Loglevel uvm. finden Sie in der Datei /opt/shibboleth-idp/conf/logback.xml. Die wichtigsten Logdateien im Überblick:

Handler

Sie können über URLs bestimmte Handler direkt aufrufen. Hier ein paar Beispiele:

Identity Provider

Logout (Session am IdP beenden): https://idp.local/idp/profile/Logout

Service Provider

Übungen

Übung 1: IdP-Module - Das User Consent-Modul

zur Doku: Logging

Bei einer Standardinstallation des IdP 4.1.x fehlt ein wichtiger Schritt: Die Nutzer*innen sollen vor der Freigabe Ihrer Daten an einen SP die Attribute aufgelistet bekommen und der Übertragung zustimmen können. Danach werden sie nur bei Änderungen am Attributset wieder gefragt. Seit Version 4.1.0 muss dafür ein Modul aktiviert werden (Hintergrundinformationen zu IdP-Modulen). Die IdP-Module werden über das Skript /opt/shibboleth-idp/bin/module.sh verwaltet. Mit der Option --help schauen Sie sich die möglichen Parameter an, mit --list die Übersicht der aktivierten und nicht aktivierten installierten Module. Nach der Installation sind nur das "Admin Hello"-Modul und das Password Authentication-Modul aktiv. Aktivieren Sie das Consent Intercept-Modul:
/opt/shibboleth-idp/bin/module.sh -e idp.intercept.Consent
Enabling idp.intercept.Consent...
        conf/intercept/consent-intercept-config.xml created
        views/intercept/attribute-release.vm created
        views/intercept/terms-of-use.vm created
[OK]
Die Terms of Use lassen wir hier weg, siehe dazu unsere oben verlinkte Dokumentation. Wir möchten jetzt lediglich die freizugebenden Attribute einblenden und abnicken lassen: Nur zur Information (nicht machen!): Wenn Sie ein bereits konfiguriertes Modul deaktivieren, wird die Konfiguration in eine .idpsave-Datei umbenannt. Von dort können Sie die Konfiguration bei Bedarf zurückkopieren.
/opt/shibboleth-idp# bin/module.sh --disable idp.intercept.Consent
Disabling idp.intercept.Consent...
        conf/intercept/consent-intercept-config.xml renamed to conf/intercept/consent-intercept-config.xml.idpsave
        views/intercept/attribute-release.vm removed
        views/intercept/terms-of-use.vm removed
[OK]

Übung 2: persistentID-Freigabe

Sie haben bei der Vorbereitung in mehreren Schritten die persistentID konfiguriert. Sie wird aus einem Quellattribut (hier: uid) und mit einem Hash errechnet und pro User und Service Provider in der MariaDB-Datenbank abgelegt. Geben Sie die persistentID für alle Service Provider frei. (Ob Sie das auf Ihrem Produktivsystem so machen, steht auf einem anderen Blatt. Hier lernen Sie erst einmal nur, wo das geht, siehe auch unsere Doku.)

Übung 3: Shibboleth-Update

Sie haben oben eine inzwischen veraltete IdP-Version installiert. Die Versionsnummer finden Sie entweder auf der IdP-Statusseite...
$ curl -s -k https://idp.local/idp/status | grep ^idp_version
... oder mit dem mitgelieferten Skript version.sh.
# /opt/shibboleth-idp/bin/version.sh
Führen Sie anhand der Dokumentation ein Update auf die aktuellste Shibboleth-Version durch. Wichtig ist, dass Sie auf die Wiederanpassung der Rechte für den Tomcat-User achten.

zur Doku: Shibboleth 4.x-Updates

Prüfen Sie erneut die Versionsnummer Ihrer Installation.

Übung 4

Setzen Sie das Loglevel für IdP, Messages und Encryption auf DEBUG hoch. Beobachten Sie das Log während der folgenden Übungen.

Übung 5

Das dfnEduPerson-Schema wird nicht mit dem Shibboleth IdP ausgeliefert. Importieren Sie es in die Attribute Registry des IdP, wie im Wiki beschrieben. Schauen Sie in die xml-Datei, um zu sehen, welche zusätzlichen Attribute das Schema mitbringt.

Übung 6

Ändern Sie die Resolver-Konfiguration für das Attribut eduPersonScopedAffiliation: Es soll keine LDAP-Abfrage mehr auf eduPersonAffiliation ausgeführt werden, sondern die Affiliation soll direkt aus der Attributdefinition im IdP geholt werden.

Übung 7

Differenzieren Sie die Attributfreigaben für SP1 und SP2 aus: In der Ausgangskonfiguration erhalten beide Service Provider dieselben Attribute. SP1 soll jetzt keine personenbezogenen Attribute übermittelt bekommen, sondern nur eduPersonScopedAffiliation. Schließen Sie den Browser in der VM, um die Session am IdP zu beenden und melden Sie sich erneut am SP1 an, z.B. mit dem Account "professorin". Prüfen Sie in /opt/shibboleth-idp/logs/idp-audit.log, ob nur eduPersonScopedAffiliation übertragen wurde:
# idp-audit.log (hier umgebrochen)
2020-10-27 14:29:06,676 - 127.0.0.2 - INFO [Shibboleth-Audit.SSO:282] - 127.0.0.2|2020-10-27T13:28:44.440493Z|
2020-10-27T13:29:06.676590Z|professorin|https://sp1.local/shibboleth|_980e6bf465fc4b22c3383ff9499f283a|password|2020-10-27T13:28:56.165603Z|
eduPersonScopedAffiliation|NMTR6SVZOCUWF5MNGDDIYQQBY4QCB76N|persistent|false|false|AES128-GCM|Redirect|POST||
Success||72d4bb621cfde876e106a9fe42369241e253b14d0b300497fbf32c8d8ace8576|
Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:82.0) Gecko/20100101 Firefox/82.0

Übung 8

Schreiben Sie ein ScriptedAttribute für das Attribut eduPersonEntitlement: Nutzen Sie die eduPersonAffiliation, um für alle Accounts, die "member" sind, das Entitlement "urn:mace:dir:entitlement:common-lib-terms" zu übertragen.

Im LDAP der VM sind passende Testaccounts: Vergleichen Sie die Logins der Accounts professorin (eduPersonAffiliation: "member") und extern (keine Affiliation). In den SAML-Assertions sehen Sie auch die übertragenen Attributwerte.

Übung 9

Am SP2 darf sich nur eine bestimmte Gruppe aus dem LDAP anmelden, nämlich die ou "politologie". Für diese befugte Gruppe erwartet der SP ein bestimmtes Entitlement vom IdP. Wandeln Sie das Skript für eduPersonEntitlement so ab, dass nur an den SP2 zusätzlich zu common-lib-terms noch das Entitlement "https://sp2.local/entitlement/politologie" übertragen wird. Der SP1 soll es nicht bekommen.

Melden Sie sich mit einem der befugten Accounts am SP2 an (polstudi oder professorin). Bei Erfolg sehen Sie nun auch hier die zugriffsgeschützte PHP-Info-Seite. Melden Sie sich zum Vergleich beim SP1 an, der für eduPersonEntitlement nur den Wert "urn:mace:dir:entitlement:common-lib-terms" bekommen sollte.

Übung 10

Geben Sie folgenden Attribute für beide SPs frei und melden Sie sich an. Schauen Sie sich im Log die übertragenen Werte an:

Lösungen zeigen