Shibboleth IdPv4 in der Schulungs-VM |
sudo su
Setzen Sie folgende Umgebungsvariablen:
# Datei: /etc/environment
JAVA_HOME="/usr/lib/jvm/java-11-openjdk-amd64/"
Laden Sie diese Umgebungsvariablen neu:
exit
sudo su
$servers->setValue('server','host','127.0.0.2');
zur Doku: Datenbank-Konfiguration
Nun legen Sie eine Datenbank für Shibboleth an. Sie wird zwei Tabellen enthalten: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;
wget -P /opt/install https://shibboleth.net/downloads/identity-provider/archive/4.2.0/shibboleth-identity-provider-4.2.0.tar.gz
wget -P /opt/install https://shibboleth.net/downloads/identity-provider/archive/4.2.0/shibboleth-identity-provider-4.2.0.tar.gz.asc
wget -P /opt/install https://shibboleth.net/downloads/PGP_KEYS
tar -xzf /opt/install/shibboleth-identity-provider-4.2.0.tar.gz -C /opt/install/
Führen Sie das interaktive Installerskript aus:
/opt/install/shibboleth-identity-provider-4.2.0/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.0] ?
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] ?
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:
<!-- 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">
<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"/>
# 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
<!-- 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>
zur Doku: Attribut-Konfiguration
wget https://download.aai.dfn.de/ws/idp2022/idpv4-attribute-resolver.xml -O /opt/shibboleth-idp/conf/attribute-resolver.xml
<!-- Datei: /opt/shibboleth-idp/conf/attribute-resolver.xml -->
<AttributeDefinition xsi:type="Simple" id="organizationalUnit">
<InputDataConnector ref="myLDAP" attributeNames="ou"/>
</AttributeDefinition>
<!-- 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>
<!-- 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).
# 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:
# Datei: /opt/shibboleth-idp/credentials/secrets.properties
idp.persistentId.salt = my-very-very-long-hash
So schalten Sie die Generierung der persistentIDs an: Entfernen Sie die Kommentarzeichen 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 folgende Zeile aktivieren. Entfernen Sie die Kommentarzeichen am Anfang und am Ende der Zeile 110:
<!-- Datei: /opt/shibboleth-idp/conf/c14n/subject-c14n.xml -->
<ref bean="c14n/SAML2Persistent" />
<!-- 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="shibboleth.JPAStorageService"
class="org.opensaml.storage.impl.JPAStorageService"
p:cleanupInterval="%{idp.storage.cleanupInterval:PT10M}"
c:factory-ref="shibboleth.JPAStorageService.EntityManagerFactory" />
<bean id="shibboleth.JPAStorageService.EntityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="packagesToScan" value="org.opensaml.storage.impl"/>
<property name="dataSource" ref="shibboleth.MySQLDataSource"/>
<property name="jpaVendorAdapter" ref="shibboleth.JPAStorageService.JPAVendorAdapter"/>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
</bean>
<bean id="shibboleth.JPAStorageService.JPAVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
p:generateDdl="true"
p:database="MYSQL"
p:databasePlatform="org.hibernate.dialect.MySQL5Dialect" />
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 = shibboleth.JPAStorageService
idp.consent.StorageService = shibboleth.JPAStorageService
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
<!-- 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>
# chown -R tomcat:tomcat /opt/shibboleth-idp/
# systemctl restart tomcat9.service
# tail -f /var/log/tomcat9/catalina.DATUM.log
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
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.
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;
# 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.
# 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
/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:
<bean parent="SAML2.SSO" p:postAuthenticationFlows="#{{'attribute-release'}}" />
2021-09-08T09:27:32.754811Z|https://sp1.local/shibboleth|AttributeReleaseConsent|professorin|eduPersonScopedAffiliation|0zLr0bShf2da65PDb/LKkNqM6tpt/cHG7wEScjDkmkw=|true
/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]
$ 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.# 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