Einführung in den Shibboleth SP

Download der Schulungs-VM und Mitschnitte

Die Schulungs-VM können Sie sich hier (.ova, 3,9 GB) herunterladen. Die Mitschnitte finden Sie auf dieser Seite.
  • Sie können den Shibboleth Service Provider mit dieser Anleitung in der VM installieren. Die weiterführenden Links zur Dokumentation sind für Ihre spätere, echte Installation gedacht.
  • Import des heruntergeladenen .ova-Images in Virtualbox: Datei → Appliance importieren
  • Für ein Copy & Paste ohne Gasterweiterungen können Sie diese Installationsanleitung selbstverständlich auch im Browser in der VM abrufen.
  • Betriebssystem der Schulungs-VM: Ubuntu 20.04
  • Alle Passwörter lauten „shibboleth“.
  • In der VM befindet sich ein LDAP-Browser (phpLDAPadmin), der im Web-Browser (Firefox) als Lesezeichen gesetzt ist.
  • Die wichtigste vorinstallierte Software:
    • Apache 2.4
    • Shibboleth IdP 4.0.1, Java 11, Tomcat 9, MariaDB 10.3, libmariadb-java
    • OpenLDAP (slapd, ldap-utils), phpldapadmin
  • Los geht's! Starten Sie die virtuelle Maschine in Virtualbox und melden Sie sich mit dem Passwort „shibboleth“ an.

Die virtuelle Maschine kommt mit einem vorkonfigurierten Shibboleth Identity Provider der aktuellen Version 4.0.1. Er holt die Attribute der Nutzer*innen aus dem LDAP-Server in der VM. Sie können über https://idp.local/phpldapadmin in der VM den LDAP-Baum einsehen. Dort stehen folgende Accounts zum Testen zur Verfügung:

uid organizationalUnit affiliations
professorin politologie staff, employee, member
lehrbeauftragter biologie faculty
polstudi politologie student, member
biostudi biologie student, member
alum kein Wert vergeben alum
extern kein Wert vergeben kein Wert vergeben

Der Identity Provider kennt folgende Attribute (siehe /opt/shibboleth-idp/conf/attribute-resolver.xml). Es sind jedoch nicht bei allen Accounts Werte für alle Attribute im LDAP eingetragen: givenName, sn, displayName, mail, ou, eduPersonAssurance, eduPersonAffiliation, eduPersonScopedAffiliation, eduPersonPrincipalName, eduPersonUniqueId, samlSubjectID, samlPairwiseID und eduPersonEntitlement. eduPersonEntitlement kann zwei Werte annehmen:

Der IdP hat folgende Filterregeln vorkonfiguriert, die bestimmen, welche Attribute an welche Service Provider übermittelt werden dürfen:

  • Filterregel „SP1“:
    • An den SP1 darf für das Multi-Value-Attribut eduPersonScopedAffiliation nur der Wert member@local übertragen werden.
    • An den SP1 darf das Multi-Value-Attribut eduPersonEntitlement nur der Wert urn:mace:dir:entitlement:common-lib-terms übertragen werden.
  • Filterregel „SP2“:
    • An den SP2 dürfen die Attribute eduPersonScopedAffiliation, surname, givenName, mail und eduPersonEntitlement übertragen werden.
    • Es gibt keine Einschränkungen in Bezug auf die Werte. Sprich: Wenn für ein Attribut mehrere Werte hinterlegt sind, werden an SP2 alle Werte übertragen.

Rufen Sie im Firefox-Browser in der VM zunächst das Lesezeichen „IdP Statusseite“ auf, um zu prüfen, ob der IdP läuft. Der Beginn der Statusseite sollte so aussehen:

### Operating Environment Information
operating_system: Linux
operating_system_version: 5.4.0-64-generic
[...]
### Identity Provider Information
idp_version: 4.0.1

Der IdP loggt nach /opt/shibboleth-idp/logs/. In idp-process.log finden Sie u.a. die SAML-Assertions, der der IdP herausschickt.

Anmerkung: Für die aktuellste SP-Version 3.2 ist noch kein Debian-Paket erschienen. Wir arbeiten daher hier mit der Version 3.1.

Doku: https://www.switch.ch/aai/docs/shibboleth/SWITCH/3.1/sp/deployment/?os=debian10

Erlangen Sie root-Rechte:

sudo su

Die Schweizer Föderation bietet ein Debian-Paket an, das dann die eigentliche Paketquelle in APT hinzufügt.

# Apt-Source als eigenes Paket herunterladen... 
wget https://pkg.switch.ch/switchaai/ubuntu/dists/focal/main/binary-all/misc/switchaai-apt-source_1.0.0~ubuntu20.04.1_all.deb -O /root/switchaai-apt-source_1.0.0~ubuntu20.04.1_all.deb
# ... und installieren
dpkg -i /root/switchaai-apt-source_1.0.0~ubuntu20.04.1_all.deb
# ... prüfen
cat /etc/apt/sources.list.d/SWITCHaai-swdistrib.list 
apt update
apt install -y --install-recommends shibboleth
# Sicherstellen, dass keine veralteten, inzwischen umbenannten, Shib SP-Pakete mehr installiert sind:
apt autoremove
  • User und Gruppe _shibd
  • In der Schulungs-VM ist der _shibd zudem in der Gruppe ssl-cert und darf daher private Schlüssel im Verzeichnis /etc/ssl/private lesen.
  • Das Verzeichnis /etc/shibboleth enthält die Konfigurationsdateien.
  • Ins Verzeichnis /var/log/shibboleth werden die Logs geschrieben.
  • Im Verzeichnis /run/shibboleth werden PID- und Socket-Dateien abgelegt.
  • In /var/cache/shibboleth werden die heruntergeladenen Metadaten gecached.

Dokumentation im Shibboleth-Wiki: shibboleth2.xml

Die zentrale Konfigurationsdatei des Shibboleth SP heißt /etc/shibboleth/shibboleth2.xml. Laden Sie sich folgende Beispieldatei zum Start herunter:

wget https://download.aai.dfn.de/ws/2021/sp-schulung/shibboleth2.xml -O /etc/shibboleth/shibboleth2.xml

Schauen Sie in die Datei: Für eine einfache, funktionierende Konfiguration sind nur wenige Stellen zu ändern. Dies ist hier bereits geschehen. In Ihrer eigenen Installation müssen Sie darauf achten, die SWITCHaai-spezifischen URLs und Zertifikate für die DFN-AAI anzupassen.

Hier sind die EntityID, eine Home-URL (hier: der Session Handler) des SPs, sowie der/die Identifier (Details s.u.) eingestellt:

<ApplicationDefaults entityID="https://sp1.local/shibboleth"
    homeURL="https://sp1.local/Shibboleth.sso/Session"
    REMOTE_USER="persistent-id uniqueID">

Die Session-Einstellungen bleiben auf den Standardeinstellungen.

Danach finden Sie die Konfiguration des Discovery Service: Innerhalb der VM werden die SPs direkt mit dem lokal laufenden IdP verbandelt:

<SSO entityID="https://idp.local/idp/shibboleth">
    SAML2
</SSO>

Darunter ist ein auskommentiertes Beispiel für die Einbindung eines Discovery Service zur Einrichtungsauswahl, nämlich unseres öffentlichen WAYFs für die DFN-AAI-Test.

Ähnlich ist es bei den einzulesenden Metadaten: In der VM nutzen wir den Metadatensatz des lokalen IdP statt - wie sonst - die Föderationsmetadaten:

<MetadataProvider type="XML" path="/opt/shibboleth-idp/metadata/idp-metadata.xml" />

Das <AttributeExtractor>-Element enthält dem Pfad zur Attribute Map des SP. Dort werden die Attribut-URNs den SP-seitige bekannten Attribute IDs zugeordnet (s.u.).

Im <AttributeFilter>-Element ist die Policy-Datei des SP verlinkt: Dort steht, welche Attribute mit welchen standardkonformen Werten belegt sein dürfen.

Zertifikat und Schlüssel für die SAML-Kommunikation: Der Typ „Chaining“ steht hier vorweg, damit für den Zertifikatstausch am SP vorübergehend zwei Credentials eingetragen werden können (Doku im Shibboleth-Wiki, Anleitung im DFN-AAI-Wiki).

<CredentialResolver type="Chaining">
  <CredentialResolver type="File"
                      key="/etc/ssl/private/sp1-key.pem"
                      certificate="/etc/ssl/certs/sp1-cert.pem"/>
</CredentialResolver>

Vor dem schließenden </ApplicationDefaults>-Element steht ein Kommentar für ApplicationOverrides. Hier werden Abweichungen definiert, z.B. für einen zweiten SP (siehe unten).

Bitte löschen Sie die mitgelieferten Beispieldateien /etc/shibboleth/example-metadata.xml und /etc/shibboleth/example-shibboleth2.xml und starten Sie den SP neu:

root@sp:~ # rm /etc/shibboleth/example-*.xml
root@sp:~ # systemctl restart shibd.service

Zusammenfassung

Der shibd ist jetzt mit Hilfe der vorkonfigurierten shibboleth2.xml lauffähig. Er enthält eine Service Provider-Konfiguration für die EntityID https://sp1.local/shibboleth und kann direkt mit dem lokalen IdP in der virtuellen Maschine kommunizieren. (An einer Föderation nimmt er nicht teil.)

Unter der URL https://sp1.local/ erreichen Sie eine noch ungeschützte phpinfo-Seite.

Zunächst schauen Sie sich bitte noch etwas in der VM um.

Da in der Schulungs-VM IdP und SPs direkt miteinander verbunden werden (also ohne das Bindeglied der Föderationsmetadaten), schauen Sie, wie das gemacht ist:

  • Der SP kennt die IdP-Metadaten aus /etc/shibboleth/shibboleth2.xml: Sie sind dort verlinkt und liegen unter /opt/shibboleth-idp/metadata/idp-metadata.xml.
  • Der IdP kennt die SP-Metadaten für sp1.local und sp2.local auch bereits. Sie liegen als Dateien unter /opt/shibboleth-idp/metadata/. Diese Dateien sind eingebunden in /opt/shibboleth-idp/conf/metadata-providers.xml (unten). Ein fertig konfigurierter Shibboleth SP stellt seine initialen Metadaten unter /Shibboleth.sso/Metadata zum Download bereit. So könnten Sie sie also herunterladen (die Zertifikatsprüfung wird nur hier in der Schulungs-VM übersprungen):
    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

Über die Variable REMOTE_USER wird in /etc/shibboleth/shibboleth2.xml der primäre Identifier der Browser-Nutzer*innen übergeben. Jedes in attribute-map.xml (s.u.) genannte Attribute kann als Quelle angegeben werden. Dazu wird die id referenziert, die in der Attribute Map steht. Bei Mehrfachnennung (mit Leerzeichen getrennt) wird das erste mit Werten befüllte Attribut verwendet.

Bei der Wahl des Identifiers für Nutzer*innen sollten verschiedene Punkte bedacht werden:

  • Der Attributwert sollte (idealerweise global) eindeutig sein. uid oder sAMAccountName können z.B. dieselben Werte annehmen, wenn der SP mit mehreren Hochschulen zusammenarbeitet.
  • Der Attributwert sollte für dieselbe Person permanent gleich bleiben.
  • Über die Zeit sollte derselbe Wert nicht für andere Nutzer*innen übermittelt werden.
  • Das Attribut sollte nur einen Wert liefern. mail eignet sich deshalb nicht.
  • Aus Datenschutzsicht ist ein Identifier zu bevorzugen, der kein SP-übergreifendes User-Tracking erlaubt wie z.B. eduPersonUniqueId, eduPersonPrincipalName oder die noch relativ neue SAML Subject ID.
  • gute Wahl: persistentId. Die SAML 2 NameID ist pseudonym und targeted, wird also pro User*in pro SP generiert und persistiert.

Alle Attribute, die der SP entgegennehmen soll, müssen in /etc/shibboleth/attribute-map.xml aufgeführt sein. Einige gängige Attribute sind in der Datei bereits als SAML 1.1- und SAML 2.0-Attribute aufgelistet. Dabei gilt für die SAML 2.0-Attribute:

  • name ist jeweils die URN, die vom IdP übermittelt wird.
  • id ist der BEzeichner, über den das Attribut SP-intern bekannt gemacht wird.
  • Weitere Angaben definieren ggf., wie das Attribute dekodiert wird, ob Groß-/Kleinschreibung berücksichtigt werden muss. Hier ein paar Beispiele (nur SAML 2.0):
    <!-- persistentId -->
    <Attribute name="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" id="persistent-id">
        <AttributeDecoder xsi:type="NameIDAttributeDecoder" formatter="$NameQualifier!$SPNameQualifier!$Name" defaultQualifiers="true"/>
    </Attribute>
    <!-- SAML Pairwise ID -->
    <Attribute name="urn:oasis:names:tc:SAML:attribute:pairwise-id" id="pairwise-id">
        <AttributeDecoder xsi:type="ScopedAttributeDecoder" caseSensitive="false"/>
    </Attribute>
    <!-- eduPersonScopedAffiliation -->
    <Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.9" id="affiliation">
        <AttributeDecoder xsi:type="ScopedAttributeDecoder" caseSensitive="false"/>
    </Attribute>
    <Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" id="unscoped-affiliation">
        <AttributeDecoder xsi:type="StringAttributeDecoder" caseSensitive="false"/>
    </Attribute>
    <!-- eduPersonEntitlement -->
    <Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.7" id="entitlement"/>

Die Datei /etc/shibboleth/attribute-policy.xml enthält einige Regeln, anhand derer der SP prüft, ob die vom IdP übermittelten Attributwert zulässig sind. Dort ist z.B. die Liste der acht möglichen Werte von eduPersonAffiliation hinterlegt:

    <!-- Shared rule for affiliation values. -->
    <PermitValueRule id="eduPersonAffiliationValues" xsi:type="OR">
        <Rule xsi:type="Value" value="faculty"/>
        <Rule xsi:type="Value" value="student"/>
        <Rule xsi:type="Value" value="staff"/>
        <Rule xsi:type="Value" value="alum"/>
        <Rule xsi:type="Value" value="member"/>
        <Rule xsi:type="Value" value="affiliate"/>
        <Rule xsi:type="Value" value="employee"/>
        <Rule xsi:type="Value" value="library-walk-in"/>
    </PermitValueRule>

Zur Doku im Shibboleth-Wiki: Apache

Mit dem Debian-Paket für den Shibboleth SP wurde u.a. ein Modul für den Apache Webserver mitinstalliert: Das Paket heißt libapache2-mod-shib und das Modul ist im Apache als mod_shib ladbar. Mit diesem Modul ist es möglich, direkt in der Konfiguration eines virtuellen Hosts Zugriffsbeschränkungen anzugeben. Dies ist die einfachste Möglichkeit, eine Ressource mit WebSSO zu schützen. Das Modul bringt diverse Dateien mit, hier die wichtigsten:

root@sp:~# dpkg -L libapache2-mod-shib
# [AUSZUG!]
/etc/apache2/conf-available/shib.conf
/etc/apache2/mods-available/shib.load
/usr/lib/apache2/modules/mod_shib.so

Das shib-Modul sollte bei der Installation automatisch geladen werden. Prüfen Sie dies:

root@sp:~# apache2ctl -M | grep shib
  mod_shib (shared)
# bei Bedarf laden Sie das Modul selbst nach:
root@sp:~# a2enmod shib
root@sp:~# cat /etc/apache2/mods-enabled/shib.load
# Inhalt:
LoadModule mod_shib /usr/lib/apache2/modules/mod_shib.so
root@sp:~# cat /etc/apache2/conf-enabled/shib.conf
# Turn this on to support "require valid-user" rules from other
# mod_authn_* modules, and use "require shib-session" for anonymous
# session-based authorization in mod_shib.
ShibCompatValidUser Off
 
# Ensures handler will be accessible.
<Location /Shibboleth.sso>
  AuthType None
  Require all granted
</Location>
 
# Used for example style sheet in error templates.
<IfModule mod_alias.c>
  <Location /shibboleth-sp>
    AuthType None
    Require all granted
  </Location>
  Alias /shibboleth-sp/main.css /usr/share/shibboleth/main.css
</IfModule>

Ohne Debian-Paket?

Wenn Sie in Ihrer Produktivumgebung kein Debian/Ubuntu verwenden, müssen Sie ggf. selbst sicherstellen, dass diese Einstellungen vorhanden sind.

Die Direktiven des Shibboleth-Moduls können innerhalb von Directory-, Files-, oder Location-Direktiven oder in .htaccess-Dateien (in Verbindung mit AllowOverride AuthConfig) untergebracht werden.

Location oder Directory?

Überlegen Sie für ein Produktivsystem, was Sie genau schützen müssen: eine URL oder einen Ort im Dateisystem? Im zweiten Fall sollten Sie mit Directory-Tags arbeiten, denn es ist möglich, einen Ordner im Dateisystem über verschiedene URLs zugänglich zu machen. Der Schutz einer URL kann so über eine andere URL womöglich umgangen werden. Ziehen Sie im Zweifel die Apache-Dokumentation hinzu.

AuthType shibboleth muss immer von mindestens einer Require-Direktive begleitet werden. Hier ein einfaches Beispiel, das lediglich eine Session am IdP verlangt, um auf die angegebene Location zuzugreifen:

<Location />
    AuthType shibboleth
    ShibRequestSetting requireSession 1
    Require valid-user
</Location>

Ein anderes Beispiel aus der Dokumentation: So können Sie eine globale Regel für einen Server oder VHost erstellen. Das Modul ist dann grundsätzlich aktiv, blockiert aber keine Zugriffe. Require shibboleth bewirkt dies. Unterhalb des Gültigkeitsbereiches können Sie dann ausdifferenzieren.

<Location />
    AuthType shibboleth
    Require shibboleth
</Location>

Anders herum: Wenn Sie eine <Location / > schützen, können Sie ein Unterverzeichnis <Location /public > ausnehmen, für das dann keine Autorisierung erforderlich ist:

<Location /public>
    AuthType Shibboleth
    ShibRequestSetting requireSession false
    Require shibboleth
</Location>

Um bestimmte Attribute auszuwerten, verwenden Sie Require shib-attr, gefolgt von dem Attribut und den zulässigen Werten oder einer regular expression. Alle in /etc/shibboleth/attribute-map.xml definierten Attribut-IDs können hier verwendet werden.

<Location />
    AuthType shibboleth
    ShibRequestSetting requireSession true
    <RequireAll>
        Require shib-attr affiliation staff@local employee@local
        Require shib-attr o Beispiel-Hochschule
    </RequireAll>
</Location>

Wie Sie hier sehen, können mehrere Require-Direktiven mitgegeben werden. Beispiele finden Sie in der Dokumentation SWITCHaai. Apache 2.4 interpretiert sie wie folgt:

  • Wenn sie einfach untereinander aufgelistet sind, dann werden sie als Oder-Verknüpfung ausgewertet: Wenn eine der Bedingungen zutrifft, wird Zugriff gewährt. Dasselbe ist der Fall, wenn die Require-Direktiven von einem <RequireAny>-Tag umschlossen sind.
  • Wenn alle Bedingungen zutreffen sollen, Sie also eine Und-Verknüpfung meinen, umschließen Sie die Zeilen mit einem <RequireAll>-Tag.

Quellen der Beispiele

Shibboleth-Wiki und SWITCHaai

So prüfen Sie, ob der Shibboleth-SP seine Konfiguration fehlerfrei laden kann:

root@sp~: shibd -t

So finden Sie eventuelle Fehler in der Konfiguration des Apache Webservers:

root@sp~: apache2ctl -t

Die relevanten Meldungen des shibd, also Probleme, die mit SAML, Metadaten oder Sicherheit zu tun haben, landen im shibd.log unter /var/log/shibboleth/shibd.log. Das Loglevel wird in /etc/shibboleth/shibd.logger konfiguriert, am einfachsten global ganz oben in der Datei ( Dokumentation im Shibboleth-Wiki).

Im Transaction-Log (/var/log/shibboleth/transaction.log) finden Sie nur die eigentlichen Transaktion, die am SP eingehen:

/var/log/shibboleth/transaction.log
2021-01-27 14:53:36|Shibboleth-TRANSACTION.Login|https://idp.local/idp/shibboleth!https://sp1.local/shibboleth!NMTR6SVZOCUWF5MNGDDIYQQBY4QCB76N|_92fcb1884c81e12eca7112a42b1eb556|https://idp.local/idp/shibboleth|_c6d1737665c193244c5c567f3d2febd0|urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport|2021-01-27T14:53:33|affiliation(3),persistent-id(1)|NMTR6SVZOCUWF5MNGDDIYQQBY4QCB76N|urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST||urn:oasis:names:tc:SAML:2.0:status:Success|||Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0|127.0.0.3

Des Weiteren gibt es den native.logger, der Meldungen des Apache-Moduls aufzeichnet, und den console.logger, der Kommandozeilen-Eingaben mit shibd loggt.

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

Service Provider

  • Metadata-Handler: So rufen Sie die bei der Installation generierten SP-Metadaten ab. In der VM bekommt der IdP sie vorgeworfen. Im echten Leben können Sie sie zum initialen Einlesen in die Metadatenverwaltung der DFN-AAI verwenden: https://sp1.local/Shibboleth.sso/Metadata (im Browser der Schulungs-VM öffnen, Seitenquelltext anzeigen).
  • Session-Handler: https://sp1.local/Shibboleth.sso/Session. Wenn Sie eine Session am SP haben, können Sie hier Details einsehen. Für die SPs in der VM finden Sie im Browser Lesezeichen zu den Session Handlern.
  • Logout-Handler am SP aufrufen: https://sp1.local/Shibboleth.sso/Logout

Identity Provider

Logout (Session am IdP beenden): https://idp.local/idp/profile/Logout (Auch hierfür gibt es ein Bookmark im Firefox der VM.)

Screencast

Die Durchführung dieser Übung können Sie in unserem Screencast ansehen.

Behalten Sie in einer separaten Konsole die Logdateien des SP im Blick:

root@sp:~# tail -f /var/log/shibboleth/shibd.log /var/log/shibboleth/transaction.log

Setzen Sie das Loglevel des shibd auf DEBUG.

/etc/shibboleth/shibd.logger
# set overall behavior
# vorher Loglevel INFO
# log4j.rootCategory=INFO, shibd_log, warn_log
# jetzt: DEBUG
log4j.rootCategory=DEBUG, shibd_log, warn_log

Starten Sie den Daemon neu:

root@sp:~# systemctl restart shibd.service

Screencast

Die Durchführung dieser Übung können Sie in unserem Screencast ansehen.

Editieren Sie die Datei /etc/shibboleth/attribute-map.xml. Nur wenige Attribute sind hier einkommentiert. Damit der SP auch die anderen Attribute erkennt, entfernen Sie bitte die Kommentarzeichen um die übrigen Attribute. Auch die eduPersonUniqueId, die weiter unten verwendet werden soll, fehlt hier noch. Ergänzen Sie:

<Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.13" id="eduPersonUniqueId"/>

.

Screencast

Die Durchführung dieser Übung können Sie in diesem Screencast ansehen.

Editieren Sie die Datei /etc/apache2/sites-enabled/sp1.conf. Fügen Sie in den VirtualHost für Port 443 folgenden oben bereits erwähnten Abschnitt ein, um beim Zugriff auf https://sp1.local eine gültige Session zu verlangen:

/etc/apache2/sites-enabled/sp1.conf
<Location />
    AuthType shibboleth
    ShibRequestSetting requireSession 1
    Require valid-user
</Location>

Laden Sie den Apache neu:

root@sp:~# systemctl reload apache2.service

Loggen Sie sich im Browser der VM am SP1 ein, z.B. mit dem Account „professorin“ (Passwort: shibboleth). Beobachten Sie die Logdateien:

Im shibd.log sehen Sie zuerst den Authentication Request an idp.local. Weiter unten sehen Sie nach dem Login die am SP eingegangene SAML-Assertion:

2021-02-03 16:55:27 DEBUG Shibboleth.SSO.SAML2 [3] [default]: decrypted Assertion: <saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="_f943258fad778186e738b4cb046fe161" IssueInstant="2021-02-03T15:55:25.509Z" Version="2.0"><saml2:Issuer>https://idp.local/idp/shibboleth</saml2:Issuer><saml2:Subject><saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml2:SubjectConfirmationData Address="127.0.0.2" InResponseTo="_6759098bc605119e9326bcf6a8c8dffb" NotOnOrAfter="2021-02-03T16:00:25.897Z" Recipient="https://sp1.local/Shibboleth.sso/SAML2/POST"/></saml2:SubjectConfirmation></saml2:Subject><saml2:Conditions NotBefore="2021-02-03T15:55:25.509Z" NotOnOrAfter="2021-02-03T16:00:25.509Z"><saml2:AudienceRestriction><saml2:Audience>https://sp1.local/shibboleth</saml2:Audience></saml2:AudienceRestriction></saml2:Conditions><saml2:AuthnStatement AuthnInstant="2021-02-03T15:55:23.346Z" SessionIndex="_25aa8c100fa8c08721a2f5b69bf71055"><saml2:SubjectLocality Address="127.0.0.2"/><saml2:AuthnContext><saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef></saml2:AuthnContext></saml2:AuthnStatement><saml2:AttributeStatement><saml2:Attribute FriendlyName="eduPersonEntitlement" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.7" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml2:AttributeValue>urn:mace:dir:entitlement:common-lib-terms</saml2:AttributeValue></saml2:Attribute><saml2:Attribute FriendlyName="eduPersonScopedAffiliation" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.9" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml2:AttributeValue>member@local</saml2:AttributeValue></saml2:Attribute></saml2:AttributeStatement></saml2:Assertion>

Hier sind v.a. die Attribute und Attributwerte interessant:

  • Für eduPersonEntitlement wurde (gemäß der Filterregeln im IdP) der Wert urn:mace:dir:entitlement:common-lib-terms übertragen.
  • Für eduPersonScopedAffiliation kam der Wert member@local.

Danach sehen Sie, dass der shibd die Attribute gemäß seiner Attribute Map von URNs in Attribute umwandelt:

2021-02-03 16:55:27 DEBUG Shibboleth.AttributeDecoder.String [3] [default]: decoding SimpleAttribute (entitlement) from SAML 2 Attribute (urn:oid:1.3.6.1.4.1.5923.1.1.1.7) with 1 value(s)
2021-02-03 16:55:27 DEBUG Shibboleth.AttributeDecoder.Scoped [3] [default]: decoding ScopedAttribute (affiliation) from SAML 2 Attribute (urn:oid:1.3.6.1.4.1.5923.1.1.1.9) with 1 value(s)
2021-02-03 16:55:27 DEBUG Shibboleth.AttributeFilter [3] [default]: filtering 2 attribute(s) from (https://idp.local/idp/shibboleth)
2021-02-03 16:55:27 DEBUG Shibboleth.AttributeFilter [3] [default]: applying filtering rule(s) for attribute (affiliation) from (https://idp.local/idp/shibboleth)
2021-02-03 16:55:27 DEBUG Shibboleth.AttributeFilter [3] [default]: applying filtering rule(s) for attribute (entitlement) from (https://idp.local/idp/shibboleth)

Rufen Sie im Browser das Lesezeichen „SP1 Session Handler“ auf. Hier können Sie jetzt Informationen über die SP-Session einsehen, inklusive der Attributwerte.

Schließen Sie den Browser in der VM, öffnen Sie ihn erneut und melden Sie sich mit dem Useraccount „extern“ an. Vergleichen Sie den Session Handler: Hier wurden keine Attribute übermittelt, es existiert nur die Session. In diesem Fall reicht das trotzdem zur Autorisierung.

Screencast

Die Durchführung dieser Übung können Sie in diesem Screencast ansehen.

Im selben virtuellen Host (sp1.local) sollen jetzt zwei Locations mit verschiedenen Autorisierungsregeln versehen werden. In den Zielverzeichnissen der beiden URLs liegen bereits index.html-Dateien bereit. Zur Erinnerung: Der Identity Provider übermittelt nur eingeschränkte Informationen an den SP1:

  • eduPersonScopedAffiliation mit dem Wert member@local
  • eduPersonEntitlement mit dem Wert urn:mace:dir:entitlement:common-lib-terms

Editieren Sie /etc/apache2/sites-enabled/sp1.conf und fügen Sie zwei neue Abschnitte ein:

    # IdP-Session reicht, um https://sp1.local aufzurufen.
    <Location />
        AuthType shibboleth
        ShibRequestSetting requireSession 1
        Require valid-user
    </Location>
 
    # Die Location https://sp1.local/members-only nur mit der Affiliation member aufgerufen werden.
    <Location /members-only>
        AuthType shibboleth
        ShibRequestSetting requireSession 1
        Require shib-attr affiliation member@local
    </Location>
 
    # Die Location https://sp1.local/library darf nur mit dem Entitlement für Bibliotheksbenutzung besucht werden.
    <Location /library>
        AuthType shibboleth
        ShibRequestSetting requireSession 1
        Require shib-attr entitlement urn:mace:dir:entitlement:common-lib-terms
    </Location>

Laden Sie den Apache neu und testen Sie: In der Lesenzeichenleiste finden Sie die beiden Locations im Ordner „SP1“. Der Account „extern“ darf auf https://sp1.local zugreifen, aber nicht auf https://sp1.local/members-only und https://sp1.local/library. Der Webserver gibt bei den beiden einen Fehler „401 Unauthorized“ zurück. Gegenprobe. Der Account „professorin“ darf auf die beiden neuen Locations zugreifen.

Screencast

Die Durchführung dieser Übung können Sie in diesem Screencast ansehen.

https://wiki.shibboleth.net/confluence/display/SP3/ApplicationOverride

Als nächstes soll im selben Webserver der VHost sp2.local geschützt werden. Er soll unter anderen Bedingungen als SP1 zugänglich sein.

Editieren Sie /etc/shibboleth/shibboleth2.xml und scrollen Sie an die Stelle, an der das Tag </ApplicationDefaults> geschlossen wird. Darüber (also innerhalb des Tags) fügen Sie folgenden Abschnitt ein:

        <ApplicationOverride id="sp2" entityID="https://sp2.local/shibboleth">
            <Sessions lifetime="28800"
                      timeout="3600"
                      checkAddress="false"
                      handlerSSL="true"
                      cookieProps="https"
                      handlerURL="https://sp2.local/Shibboleth.sso" />
            <CredentialResolver type="File"
                                key="/etc/ssl/private/sp2-key.pem"
                                certificate="/etc/ssl/certs/sp2-cert.pem"/>
        </ApplicationOverride>

Sie konfigurieren damit eine zusätzliche „Application“ mit der ID „sp2“, einer eigenen EntityID, einem eigenen Handler und Zertifikat.

Speichern Sie die Datei und starten Sie den shibd neu:

root@sp:~ # systemctl restart shibd.service

Editieren Sie den dazugehörigen Apache-VHost /etc/apache2/sites-enabled/sp2.conf und fügen Sie in das <VirtualHost>-Tag für Port 443 eine Zugangsbeschränkung ein. Beide Bedingungen (bestimmte Affiliations und ein bestimmtes Entitlement) müssen erfüllt sein:

    <Location />
        AuthType shibboleth
        # Hier geben Sie die oben gesetzte ID des 2. SP an:
        ShibRequestSetting applicationId sp2
        ShibRequestSetting requireSession 1
        <RequireAll>
            Require shib-attr affiliation staff@local employee@local faculty@local
            Require shib-attr entitlement https://sp2.local/entitlement/politologie
        </RequireAll>
    </Location>

Speichern Sie die Datei und laden Sie den Apache neu:

root@sp:~ # systemctl reload apache2.service

Der einzige Account, der sich jetzt am SP2 anmelden kann, ist „professorin“.

Die nachfolgende Anleitung basiert auf der offiziellen Dokumentation unter https://wiki.shibboleth.net/confluence/display/SP3/JavaHowTo und nimmt hierzu einige Ergänzungen vor.

Systemaufbau

Für dieses Szenario wird ein Apache Webserver mit einem shibd als Reverse Proxy zu einem Tomcat Webserver verwendet. Die Kommunikation zwischen dem Apache und Tomcat erfolgt über AJP (Apache JServ Protocol). Da hierbei der Tomcat die Authentifizierungsverantwortung an den Apache abgibt, sollte bereits auf Netzwerkebene sichergestellt werden, dass ein direkter Zugriff auf den Tomcat nur von dem Apache Webserver möglich ist. Das einfachste Setup besteht aus einem Apache- und einer Tomcat-Instanz gemeinsam auf einem Server. Dabei wird der Connector für den Tomcat AJP nur an localhost gebunden.

Konfiguration Shibboleth Service Provider

Möchte man nur den Username des angemeldeten Benutzers an einen Tomcat übergeben, so reicht es, in der shibboleth2.xml in dem Element <ApplicationDefaults> das Attribut REMOTE_USER zu definieren. Als Wiederholung: Als Wert wird eine durch Leerzeichen getrennte Liste von Attribut-IDs aus der attribute-map.xml erwartet. Diese Liste wird entsprechend der angegebenen Reihenfolge abgearbeitet. Das erste Attribut, das einen nicht leeren Wert enthält, wird als REMOTE_USER verwendet.

Möchte man neben dem REMOTE_USER noch weitere Attribute aus einer Shibboleth-Session an den Tomcat via AJP weiterreichen, so muss in der shibboleth2.xml in dem Element ApplicationDefaults zusätzlich das Attribut attributePrefix mit dem Wert AJP_ gesetzt werden. Alternativ kann man auch einzelnen Attributen in der attribute_map.xml das Präfix AJP_ vorsetzen. Im ersten Fall erscheint der Attributname im Environment vom Apache ohne den AJP_ Präfix, im zweiten Fall jedoch mit. In der Umgebung des Tomcats werden die Attributnamen in beiden Fällen ohne den Präfix AJP_ ausgewiesen.

Je nach Komplexität der Shibboleth Konfiguration können die Attribute REMOTE_USER und attributePräfix auch in dem Element <ApplicationOverride> gesetzt oder überschrieben werden.

Editieren Sie das Element <ApplicationOverride> in der /etc/shibboleth/shibboleth2.xml und ergänzen Sie die Attribute REMOTE_USER und attributePrefix:

        <ApplicationOverride 
            id="sp2"
            entityID="https://sp2.local/shibboleth"
            REMOTE_USER="persistent-id"
            attributePrefix="AJP_">
 
            <Sessions lifetime="28800"
                      timeout="3600"
                      checkAddress="false"
                      handlerSSL="true"
                      cookieProps="https"
                      handlerURL="https://sp2.local/Shibboleth.sso" />
            <CredentialResolver type="File"
                                key="/etc/ssl/private/sp2-key.pem"
                                certificate="/etc/ssl/certs/sp2-cert.pem"/>
        </ApplicationOverride>

Starten Sie wieder den shibd neu:

root@sp:~# systemctl restart shibd.service

Konfiguration Tomcat

Damit der Tomcat die Authentifizierungsverantwortung abgibt, muss im Connector für AJP das Attribut tomcatAuthentication=„false“ gesetzt werden.

Ab der Tomcat Version 8.5 müssen die zusätzlichen Attribute, die man an einen Tomcat aus dem Apache Shibboleth Environment weitergeben möchte, explizit angegeben werden. Hierfür muss im Connector für AJP im Attribut allowedRequestAttributesPattern ein regulärer Ausdruck angegeben werden, der die gewünschten Attributnamen abdeckt. allowedRequestAttributesPattern=„.*“ erlaubt alles, sollte aber aus Sicherheitsgründen nur für Tests angewendet werden.

Es kann vorkommen, dass die Standard packetSize mit 8192 Bytes für die Gesamtmenge an zu übertragenden Environment-Daten nicht ausreicht. In diesem Fall kann das Attribut mit packetSize=„65536“ auf das Maximum im Connector für AJP gesetzt werden.

Die offizielle Dokumentation zum Connector für AJP finden Sie unter: https://tomcat.apache.org/tomcat-9.0-doc/config/ajp.html

In der Schulungs-VM führen Sie bitte folgende Kommandos aus, um den Connector für AJP gemäß den zuvor genannten Ausführungen anzupassen und eine Testseite anzulegen:

/etc/tomcat9/server.xml
    <Connector port="8009"
               address="127.0.0.1"
               protocol="AJP/1.3"
               redirectPort="8443"
               enableLookups="false"
               useIPVHosts="true"
               maxPostSize="100000"
               URIEncoding="UTF-8"
               secretRequired="false"
               tomcatAuthentication="false"
               allowedRequestAttributesPattern="^(Shib-.*|givenName|sn|mail|affiliation|entitlement|persistent-id)$"/>

Die Änderung erfordert einen Neustart des Tomcat:

root@sp:~# systemctl restart tomcat9.service

Die Mini-Anwendung, die Ihnen die übergebenen Attribute anzeigt, ist bereits vorbereitet:

/var/lib/tomcat9/webapps/testapp/index.jsp
<p>REMOTE_USER: <%= request.getRemoteUser() %></p>
<p>givenName: <%= request.getAttribute("givenName") %></p>
<p>sn: <%= request.getAttribute("sn") %></p>
<p>mail: <%= request.getAttribute("mail") %></p>
<p>entitlement: <%= request.getAttribute("entitlement") %></p>
<p>affiliation: <%= request.getAttribute("affiliation") %></p>
<p>persistent-id: <%= request.getAttribute("persistent-id") %></p>
<p>Shib-Application-ID: <%= request.getAttribute("Shib-Application-ID") %></p>
<p>Shib-Session-ID: <%= request.getAttribute("Shib-Session-ID") %></p>
<p>Shib-Identity-Provider: <%= request.getAttribute("Shib-Identity-Provider") %></p>
<p>Shib-Authentication-Instant: <%= request.getAttribute("Shib-Authentication-Instant") %></p>
<p>Shib-Authentication-Method: <%= request.getAttribute("Shib-Authentication-Method") %></p>
<p>Shib-AuthnContext-Class: <%= request.getAttribute("Shib-AuthnContext-Class") %></p>
<p>Shib-AuthnContext-Decl: <%= request.getAttribute("Shib-AuthnContext-Decl") %></p>
<p>Shib-Handler: <%= request.getAttribute("Shib-Handler") %></p>

Konfiguration Apache

Die Anbindung des Tomcat über den Apache Webserver kann mit dem Modul mod_proxy_ajp vorgenommen werden. Eine Anleitung hierzu finden Sie unter https://httpd.apache.org/docs/current/mod/mod_proxy_ajp.html

Es wird dazu geraten, grundsätzlich die Locations für die Shibboleth-Handler mit ProxyPass /Shibboleth.sso/* ! auszunehmen.

Wenn im AJP Connector vom Tomcat die packetSize angepasst wurde (z.B. packetSize=„65536“) muss im Apache auch noch der Parameter ProxyIOBufferSize gesetzt werden (z.B. ProxyIOBufferSize 65536)

Bitte führen Sie folgende Konfigurationsschritte aus:

1. Sicherstellen, dass mod_proxy und mod_proxy_ajp im Apache aktiviert sind (Dies ist in der Schulungs-VM bereits der Fall, da der IdP sie ebenfalls verwendet):

root@sp:~# a2enmod proxy
root@sp:~# a2enmod proxy_ajp

2. testapp vom Tomcat in der VHost-Konfiguration von sp2 einbinden:

/etc/apache2/sites-enabled/sp2.conf
    <Location />
        AuthType shibboleth
        ShibRequestSetting applicationId sp2
        ShibRequestSetting requireSession 1
        # Erweitern Sie hier die Autorisierungsregel...
        Require valid-user
    </Location>
 
    <Location /testapp>
        AuthType shibboleth
        ShibRequestSetting applicationId sp2
        ShibRequestSetting requireSession 1
        # ... und schränken Sie hier dafür den Zugriff ein:
        <RequireAll>
            Require shib-attr affiliation staff@local employee@local faculty@local
            Require shib-attr entitlement https://sp2.local/entitlement/politologie
        </RequireAll>
    </Location>
 
    ProxyPass /Shibboleth.sso/* !
    ProxyPass "/testapp" "ajp://localhost:8009/testapp"
    ProxyPassReverse "/testapp" "ajp://localhost:8009/testapp"

3. Veränderte Konfiguration laden

root@sp:~# systemctl reload apache2.service

4. Überprüfen des Konfigurationserfolgs

Rufen Sie https://sp2.local/testapp/ auf und Sie sollten die Attribute aus Ihrer index.jsp sehen.

Alternativ zu mod_proxy_ajp kann auch mod_jk verwendet werden. Siehe hierzu: http://tomcat.apache.org/connectors-doc/

Problem mehrerer Sessions / Session Cookies

Wenn nach einer erfolgreichen Authentifizierung am Shibboleth Service Provider in einer Java Webanwendung im Tomcat eine weitere Session anhand des REMOTE_USER initiert wird, entsteht mindestens ein weiteres Session Cookie. Hiermit kann eine personalisierte Session und Contexte verbunden sein. Bei einem Logout oder anderen Vorgängen werden die Informationen unter Umständen nicht vollständig invalidiert. Wenn sich an einem Browser dann nachfolgend ein anderer Nutzer anmeldet, können problematische Personalisierungs- und Rechtesituationen entstehen. Dies sollte in jedem Fall geprüft werden. Man kann z.B. den REMOTE_USER oder die Shib-Session-ID in alle zugehörigen Session- und Contextcontainer hineinschreiben. Bei jedem Request kann man dann mit einem Servlet Filter prüfen, ob übermittelter REMOTE_USER/Shib-Session-ID mit den Werten in den Containern übereinstimmen und bei negativen Ergebnis alles invalidieren.

Screencast

Die Durchführung dieser Übung können Sie in diesem Screencast ansehen.
  • Moodle-Verzeichnis: /var/www/moodle
  • lokaler Moodle-Admin: shibboleth, Passwort: Shibboleth1!
  • a2ensite moodle.conf

Plugin-Konfiguration

  • Eingeloggt: Website-Administration → Plugins → Authentifizierung → Übersicht: Am Auge ist zu erkennen, dass das Shibboleth-Plugin aktiv ist. Die Einstellungen:
    • Anmeldename: Hier kommt der Identifier, der REMOTE_USER, rein. Die persistentId kann leider nicht als Identifier verwendet werden, weil sie Zeichen enthalten kann, die Moodle nicht im Username erlaubt. Als REMOTE_USER ist daher eduPersonUniqueId konfiguriert. (eduPersonPrincipalName ist an dieser Stelle auch gängig.)
    • Moodle WAYF Service: in der Schulungs-VM: nein! Hier wird der Moodle-SP auch direkt mit dem idp.local verbunden. Wenn der WAYF gewählt wird, hat man im Standard-Interface keinen Login-Button für lokal.
    • Identity Provider: Hier werden die EntityId, ein String zur Beschreibung und optional der Shibboleth Session Initiator eingetragen:https://idp.local/idp/shibboleth, IdP local, /Shibboleth.sso/Login
    • Shibboleth Service Provider Logout URL Handler https://moodle.local/Shibboleth.sso/Logout (Standard)
    • Name der Authentifierungsmethode: hier: Single Sign-On, wird auf der Loginseite angezeigt
    • Logo: ein Logo, das die Leute mit ihrem Hochschul-Login verbinden.
    • Datenzuordnung: Welche Attribute sollen wie in Moodle übernommen werden? Dürfen die Nutzer*innen sie in Moodle ändern? Sollen die Werte bei jedem Loginvorgang aktualisiert werden?
      • Vorname: givenName
      • Nachname: sn
      • E-Mail-Adresse: mail
      • Institution: o

Konfiguration der Autorisierung

  • Alle Accounts mit der eduPersonScopedAffiliation student@local sollen sich anmelden können.
  • eigener Apache VHost /etc/apache2/sites-available/moodle.conf (a2ensite).
    • Laut Dokumentation muss das Directory /var/www/moodle/auth/shibboleth/index.php geschützt werden. Hier wird zur Autorisierung verlangt, dass die Personen die eduPersonScopedAffiliation mit dem Wert student@local vorweisen:
          <Directory /var/www/moodle/auth/shibboleth/index.php>
              AuthType shibboleth
              ShibRequestSetting requireSession 1
              Require shib-attr affiliation student@local
          </Directory>
  • der Einfachheit halber eigene shibboleth2.xml (nicht dieselbe wie in den obigen Übungen) mit REMOTE_USER eduPersonUniqueId und ohne ApplicationOverrides
  • Zuletzt geändert: vor 7 Wochen