Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
de:shibidp:config-storage [2020/04/09 16:40] – [Verarbeitung anschalten] Silke Meyerde:shibidp:config-storage [2023/07/31 12:10] (aktuell) – [Generierung und Speicherung] klarerer Hinweise auf randomness des Salt Silke Meyer
Zeile 1: Zeile 1:
 +<-  de:shibidp:config-tou|Nutzungsbedingungen ^ de:shibidp:uebersicht|Überblick: Tutorial zur IdP-Inbetriebnahme ^ de:shibidp:config-slo|Single Logout ->
 ~~NOTOC~~ ~~NOTOC~~
-====== Server-Side Storage ======+====== Server-Side Storage und persistent Id ======
 {{INLINETOC 2}} {{INLINETOC 2}}
  
 Standardmäßig werden Informationen zu Sessions, User Consent (bzgl. Attributfreigabe) und Persistent IDs clientseitig in Cookies abgelegt. Wir betrachten die clientseitige Speicherung nur als initiale "Notlösung", damit der IdP auch ohne Datenbank funktioniert. In einem fertigen Produktivszenario ist das Abspeichern dieser Informationen auf Serverseite unbedingt zu empfehlen, da nur damit erweiterte SAML-Funktionalitäten möglich sind (z.B. persistentIds oder Single-Logout). Nur so kann sichergestellt werden, dass bei Attribute Queries, die Entscheidungen des/der Nutzers/Nutzerin hinsichtlich Attributfreigabe berücksichtigt werden. Standardmäßig werden Informationen zu Sessions, User Consent (bzgl. Attributfreigabe) und Persistent IDs clientseitig in Cookies abgelegt. Wir betrachten die clientseitige Speicherung nur als initiale "Notlösung", damit der IdP auch ohne Datenbank funktioniert. In einem fertigen Produktivszenario ist das Abspeichern dieser Informationen auf Serverseite unbedingt zu empfehlen, da nur damit erweiterte SAML-Funktionalitäten möglich sind (z.B. persistentIds oder Single-Logout). Nur so kann sichergestellt werden, dass bei Attribute Queries, die Entscheidungen des/der Nutzers/Nutzerin hinsichtlich Attributfreigabe berücksichtigt werden.
  
-<callout type="danger" title="persistentId?">+<callout color="#ff9900" title="persistentId?">
 PersistentIds werden vom IdP pro Useraccount und pro Service Provider automatisch generiert. Sie sind pseudonym und können am SP zur Wiedererkennung und Personalisierung verwendet werden. Nur am IdP ist ist ersichtlich, welchen Nutzer*innen die persistentIds zuzuordnen sind. persistentIds sind keine normalen Attribute, sondern sogenannte SAML2 NameIDs. Ihre Freigabe wird in der Konfigurationsdatei ''./conf/relying-party.xml'' reguliert. PersistentIds werden vom IdP pro Useraccount und pro Service Provider automatisch generiert. Sie sind pseudonym und können am SP zur Wiedererkennung und Personalisierung verwendet werden. Nur am IdP ist ist ersichtlich, welchen Nutzer*innen die persistentIds zuzuordnen sind. persistentIds sind keine normalen Attribute, sondern sogenannte SAML2 NameIDs. Ihre Freigabe wird in der Konfigurationsdatei ''./conf/relying-party.xml'' reguliert.
 </callout> </callout>
  
-<callout type="danger" title="Attribute Query?">+<callout color="#ff9900" title="Attribute Query?">
 Bei einer Attribute Query fragt ein Service Provider direkt beim IdP Nutzerdaten ab, also ohne, dass Nutzer*innen einen Loginvorgang angestoßen haben. Dies tun manche SPs, um Informationen darüber zu bekommen, ob Useraccounts am IdP noch aktiv sind. Für Attribute Queries wird gerne die persistentId verwendet. Bei einer Attribute Query fragt ein Service Provider direkt beim IdP Nutzerdaten ab, also ohne, dass Nutzer*innen einen Loginvorgang angestoßen haben. Dies tun manche SPs, um Informationen darüber zu bekommen, ob Useraccounts am IdP noch aktiv sind. Für Attribute Queries wird gerne die persistentId verwendet.
 </callout> </callout>
Zeile 17: Zeile 18:
  
 ==== Installation ==== ==== Installation ====
 +Im einfachsten Fall installieren Sie auf dem IdP einen lokalen Datenbank-Server. Sie können natürlich auch entfernte Datenbanken über das Netzwerk einbinden.
  
 <code bash> <code bash>
Zeile 31: Zeile 33:
 root@idp:~# systemctl restart tomcat9 root@idp:~# systemctl restart tomcat9
 </code> </code>
 +
 +Installieren Sie schließlich im IdP (ab Version 4.2!) das JDBC-Plugin:<code bash>root@idp:~# /opt/shibboleth-idp/bin/plugin.sh -I net.shibboleth.plugin.storage.jdbc</code>
  
 ==== Datenbank und Tabellen anlegen ==== ==== Datenbank und Tabellen anlegen ====
  
 Die Datenbank und der Datenbank-Benutzeraccount müssen manuell erstellt werden. Dann werden noch zwei Tabellen angelegt:  Die Datenbank und der Datenbank-Benutzeraccount müssen manuell erstellt werden. Dann werden noch zwei Tabellen angelegt: 
-  * ''StorageRecords'' für Sessions und User Consent-Informationen+  * ''StorageRecords'' für Sessions und User Consent-Informationen (die COLLATION muss case-sensitive sein, hier utf8_bin)
   * ''shibpid'' für die persistentIds   * ''shibpid'' für die persistentIds
  
Zeile 52: Zeile 56:
   version bigint(20) NOT NULL,   version bigint(20) NOT NULL,
   PRIMARY KEY (context, id)   PRIMARY KEY (context, id)
-);+COLLATE utf8_bin;
  
 mysql> CREATE TABLE IF NOT EXISTS shibpid ( mysql> CREATE TABLE IF NOT EXISTS shibpid (
Zeile 73: Zeile 77:
 </code> </code>
  
-==== JPAStorageService konfigurieren ====+==== JDBCStorageService konfigurieren ====
  
-Der DB-Zugriff wird über den [[https://wiki.shibboleth.net/confluence/display/IDP4/StorageConfiguration#StorageConfiguration-JPAStorageService|JPAStorageService]] gekapselt. Dieser wird in ''./conf/global.xml'' definiert. Diese Datei ist im Auslieferungszustand leer (bis auf Kommentare). Füllen Sie sie wie folgt:+Der DB-Zugriff wird über den [[https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/pages/2989096970/JDBCStorageService|JDBCStorageService]] hergestellt. Dieser wird in ''./conf/global.xml'' definiert. Diese Datei ist im Auslieferungszustand leer (bis auf Kommentare). Füllen Sie sie wie folgt:
  
 <file xml ./conf/global.xml> <file xml ./conf/global.xml>
Zeile 113: Zeile 117:
               p:validationQueryTimeout="5" />               p:validationQueryTimeout="5" />
  
-        <bean id="shibboleth.JPAStorageService+        <bean id="JDBCStorageService
-              class="org.opensaml.storage.impl.JPAStorageService"+              parent="shibboleth.JDBCStorageService"
               p:cleanupInterval="%{idp.storage.cleanupInterval:PT10M}"               p:cleanupInterval="%{idp.storage.cleanupInterval:PT10M}"
-              c:factory-ref="shibboleth.JPAStorageService.EntityManagerFactory" /> +              p:dataSource-ref="shibboleth.MySQLDataSource" />
- +
-        <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" /> +
 </beans> </beans>
 </file> </file>
Zeile 168: Zeile 155:
 Wählen Sie ein Quellattribut aus Ihrem IdM, das **über die Zeit eindeutig** bleibt! Bei OpenLDAP ist das oft die ''uid'', bei Active Directory der ''sAMAccountName'' oder ''cn''. Wenn Sie diese Attribute für neue Accounts wiederverwenden, dann //müssen// Sie ein anderes IdM-Attribut zur Generierung der persistentId verwenden. Wählen Sie ein Quellattribut aus Ihrem IdM, das **über die Zeit eindeutig** bleibt! Bei OpenLDAP ist das oft die ''uid'', bei Active Directory der ''sAMAccountName'' oder ''cn''. Wenn Sie diese Attribute für neue Accounts wiederverwenden, dann //müssen// Sie ein anderes IdM-Attribut zur Generierung der persistentId verwenden.
  
-Ein möglicher Workaround: Sie können sich in der ''./conf/attribute-resolver.xml'' ein neues Attribut definieren. Dieses Attribut könnte aus einem Hash aus uid und dem Anlegedatum des Accounts bestehen. Beispiele zur Generierung finden Sie unter [[:de:shibidp3pidspecials|Persistent ID - Sonderfälle]].+Ein möglicher Workaround: Sie können sich in der ''./conf/attribute-resolver.xml'' ein neues Attribut definieren. Dieses Attribut könnte aus einem Hash aus uid und dem Anlegedatum des Accounts bestehen. Beispiele zur Generierung finden Sie unter [[de:shibidp:config-pidspecials|Persistent ID - Sonderfälle]].
  
 ==== Generierung und Speicherung ==== ==== Generierung und Speicherung ====
-Das gewählte Quellattribut legen Sie in ''./conf/saml-nameid.properties'' fest: Schauen Sie in ''.conf/attribute-resolver.xml'' nach, welche "id" das Quellattribut hat und tragen Sie sie hier ein. Es wird //nicht// der originale Attribut-Name aus dem IdM verwendet! Der Hash sollte möglichst lang und beliebig sein und mit niemandem geteilt werden. Schließlich stellen Sie hier noch ein, dass die persistenIds in der MySQL-Datenbank gespeichert werden sollen.+ 
 +Das gewählte Quellattribut legen Sie in ''./conf/saml-nameid.properties'' fest: Schauen Sie in ''./conf/attribute-resolver.xml'' nach, welche "id" das Quellattribut hat und tragen Sie sie hier ein. Es wird //nicht// der originale Attribut-Name aus dem IdM verwendet! Hier stellen Sie auch ein, dass die persistentIds in der MySQL-Datenbank gespeichert werden sollen.
  
 <file properties /opt/shibboleth-idp/conf/saml-nameid.properties> <file properties /opt/shibboleth-idp/conf/saml-nameid.properties>
 idp.persistentId.sourceAttribute = uid idp.persistentId.sourceAttribute = uid
-idp.persistentId.useUnfilteredAttributes = true +BASE64 will match V2 valueswe recommend BASE32 encoding for new installs
-# Do *NOT* share the salt with other peopleit's like divulging your private key. +idp.persistentId.encoding BASE32
-# idp.persistentId.algorithm = SHA +
-idp.persistentId.salt MöglichstBeliebigUndGeHeim-mindestens-16bytes+
  
 # To use a database, use shibboleth.StoredPersistentIdGenerator # To use a database, use shibboleth.StoredPersistentIdGenerator
Zeile 184: Zeile 170:
 # For basic use, set this to a JDBC DataSource bean name: # For basic use, set this to a JDBC DataSource bean name:
 idp.persistentId.dataSource = shibboleth.MySQLDataSource idp.persistentId.dataSource = shibboleth.MySQLDataSource
 +
 </file> </file>
 +
 +Der Salt-Hash, mit dem die persistentIds generiert werden, wird aus Sicherheitsgründen in der zugriffsbeschränkten Passwortdatei ''./credentials/secrets.properties'' hinterlegt. Er sollte möglichst beliebig, also zufällig generiert, und möglichst lang sein und mit niemandem geteilt werden.
 +
 +<file properties /opt/shibboleth-idp/credentials/secrets.properties>
 +# Bitte durch einen zufällig generierten Salt ersetzen!
 +idp.persistentId.salt = my-very-very-long-hash
 +
 +</file>
 +
  
 ==== Generator anschalten ==== ==== Generator anschalten ====
Zeile 228: Zeile 224:
 Meist sind Usernamen in IdM-Systemen unabhängig von Groß- und Kleinschreibung: Nutzer*innen können ihre Anmeldenamen sowohl groß, als auch klein schreiben und sich damit erfolgreich anmelden. Die IdP-Datenbank unterscheidet jedoch zwischen Groß- und Kleinschreibung. Wir empfehlen daher, alle Usernamen im IdP in Kleinbuchstaben zu verarbeiten: Meist sind Usernamen in IdM-Systemen unabhängig von Groß- und Kleinschreibung: Nutzer*innen können ihre Anmeldenamen sowohl groß, als auch klein schreiben und sich damit erfolgreich anmelden. Die IdP-Datenbank unterscheidet jedoch zwischen Groß- und Kleinschreibung. Wir empfehlen daher, alle Usernamen im IdP in Kleinbuchstaben zu verarbeiten:
  
 +=== bis IdP 4.0.1 ===
 <file xml ./conf/c14n/simple-subject-c14n-config.xml> <file xml ./conf/c14n/simple-subject-c14n-config.xml>
    ...    ...
    <util:constant id="shibboleth.c14n.simple.Lowercase" static-field="java.lang.Boolean.TRUE"/>    <util:constant id="shibboleth.c14n.simple.Lowercase" static-field="java.lang.Boolean.TRUE"/>
    ...    ...
 +</file>
 +
 +=== ab IdP 4.1.0 ===
 +<file properties ./conf/c14n/subject-c14n.properties>
 +idp.c14n.simple.lowercase = true
 +</file>
 +
 +===== Data Connector =====
 +Stellen Sie sicher, dass Ihre ''./conf/attribute-resolver.xml'' unten bei den Data Connectors einen Abschnitt für die Datenbank enthält. Er kann dann als ''InputDataConnector'' in Attribut-Definitionen verwendet werden, in denen die persistentId verwendet werden soll (z.B. für die [[de:common_attributes#a17|samlPairwiseID]] (Wert der persistentId + Scope)).
 +
 +<file xml ./conf/attribute-resolver.xml>
 +    <DataConnector id="StoredId"
 +        xsi:type="StoredId"
 +        generatedAttributeID="persistentId"
 +        salt="%{idp.persistentId.salt}">
 +        <InputAttributeDefinition ref="%{idp.persistentId.sourceAttribute}" />
 +        <BeanManagedConnection>shibboleth.MySQLDataSource</BeanManagedConnection>
 +    </DataConnector>
 </file> </file>
  
 ===== Session-Informationen und User Consent ===== ===== Session-Informationen und User Consent =====
  
-Nachdem Datenbankverbindung und persistentId aktiviert sind, können diese nun für die Speicherung von Session- und User Consent-Informationen genutzt werden. Dadurch wird als netter Nebeneffekt auch [[:de:shibidp3slo|SingleLogout-Unterstützung]] im IdP ermöglicht.+Nachdem Datenbankverbindung und persistentId aktiviert sind, können diese nun für die Speicherung von Session- und User Consent-Informationen genutzt werden. Dadurch wird als netter Nebeneffekt auch [[de:shibidp:config-slo|SingleLogout-Unterstützung]] im IdP ermöglicht.
  
 <file properties /opt/shibboleth-idp/conf/idp.properties> <file properties /opt/shibboleth-idp/conf/idp.properties>
 ... ...
 # Set to "shibboleth.StorageService" for server-side storage of user sessions # Set to "shibboleth.StorageService" for server-side storage of user sessions
-idp.session.StorageService = shibboleth.JPAStorageService+idp.session.StorageService = JDBCStorageService
  
 # Set to "shibboleth.StorageService" or custom bean for alternate storage of consent # Set to "shibboleth.StorageService" or custom bean for alternate storage of consent
-idp.consent.StorageService = shibboleth.JPAStorageService+idp.consent.StorageService = JDBCStorageService
  
 # Set to "shibboleth.consent.AttributeConsentStorageKey" to use an attribute # Set to "shibboleth.consent.AttributeConsentStorageKey" to use an attribute
Zeile 268: Zeile 283:
 ===== User Consent zu Attributfreigabe bei Attribute Queries berücksichtigen ===== ===== User Consent zu Attributfreigabe bei Attribute Queries berücksichtigen =====
  
-Damit bei Attribute Queries Nutzer-Entscheidungen zur Attributfreigabe berücksichtigt werden, muss in ./conf/intercept/consent-intercept-config.xml die entsprechende Condition gesetzt werden:+Damit bei Attribute Queries Nutzer-Entscheidungen zur Attributfreigabe berücksichtigt werden, muss in ''./conf/intercept/consent-intercept-config.xml'' die entsprechende Condition gesetzt werden. Ab dem IdP 4.1.0 müssen Sie zunächst das [[https://wiki.shibboleth.net/confluence/display/IDP4/ConsentConfiguration|Intercept Consent-Modul aktivieren]], damit Sie die Datei überhaupt haben:<code bash>bin/module.sh -t idp.intercept.Consent || bin/module.sh -e idp.intercept.Consent</code> 
 + 
 +Dann modifizieren Sie die Datei wie folgt:
  
 <file xml ./conf/intercept/consent-intercept-config.xml> <file xml ./conf/intercept/consent-intercept-config.xml>
Zeile 308: Zeile 325:
  
 <code bash> <code bash>
-root@idp:/opt/shibboleth-idp# service tomcat8 restart+root@idp:/opt/shibboleth-idp# systemctl restart tomcat9
 </code> </code>
  
Zeile 315: Zeile 332:
 HINWEIS: Da die persistendId kein SAML-Attribut ist, wird Ihnen diese nach dem Login am IdP nicht in der Liste der zu übertragenden Attribute angezeigt. Erst wenn Sie wieder am Test-SP sind wird Ihnen dort die persistentId, sofern diese übertragen wurde, zusammen mit den übertragenen Attributen angezeigt. HINWEIS: Da die persistendId kein SAML-Attribut ist, wird Ihnen diese nach dem Login am IdP nicht in der Liste der zu übertragenden Attribute angezeigt. Erst wenn Sie wieder am Test-SP sind wird Ihnen dort die persistentId, sofern diese übertragen wurde, zusammen mit den übertragenen Attributen angezeigt.
  
-Falls die persistentId nur an ausgewählte SPs übertragen werden soll, so finden sich [[:de:shibidp3pidspecials|hier einige Beispiele]].+Falls die persistentId nur an ausgewählte SPs übertragen werden soll, so finden sich [[de:shibidp:config-pidspecials|hier einige Beispiele]].
  
-**Weiter geht es mit [[:de:shibidp3slo|Single Logout]]. **+===== Umstellung auf SAML pairwise-id ===== 
 +Die persistentID und das funktionsanaloge, als deprecated geltende Attribut [[de:common_attributes#a11|eduPersonTargetedID]] sollen in Zukunft von der [[de:common_attributes#a17|SAML pairwise-id]] ([[de:shibidp:config-attributes-aaiplus|Konfigurationsbeispiel]]) abgelöst werdenDie erlaubten Werte der pairwise-id unterscheiden sich allerdings von denen der persistentID (siehe die [[https://docs.oasis-open.org/security/saml-subject-id-attr/v1.0/saml-subject-id-attr-v1.0.html|Spezifikation]]): 
 +  Die pairwise-id hat einen Scope. 
 +  Die Werte werden mit BASE32 statt mit BASE64 kodiert. Sie dürfen also weniger Zeichen enthalten als alte persistentIDs und sind case-insensitive zu behandeln.
  
 +Für die Umstellung der persistentID auf die pairwise-id gibt es keinen perfekten Weg. Wir empfehlen folgendes Vorgehen, mit dem Sie vermeiden, alle Service Provider die persistentIDs bestehender Accounts umschreiben zu lassen:
 +  * Ändern Sie im IdP das Encoding der persistentIDs auf BASE32. Damit erreichen Sie, dass **//neu generierte// persistentIDs** so kodiert werden, dass sie als Basis für standardkonforme pairwise-ids verwendet werden können.<file properties /opt/shibboleth-idp/conf/saml-nameid.properties>
 +# BASE64 will match V2 values, we recommend BASE32 encoding for new installs.
 +idp.persistentId.encoding = BASE32</file>
 +  * Setzen Sie auch beim entsprechenden Data Connector in ''conf/attribute-resolver.xml'' das Encoding auf BASE32 wie in diesem Beispiel (siehe auch [[https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631589/StoredIdConnector|StoredIdConnector im Shibboleth-Wiki]]):<file xml /opt/shibboleth-idp/conf/attribute-resolver.xml>
 +    <DataConnector id="StoredId"
 +        xsi:type="StoredId"
 +        generatedAttributeID="persistentID"
 +        salt="%{idp.persistentId.salt}"
 +        encoding="BASE32"
 +        queryTimeout="0">
 +        <InputAttributeDefinition ref="%{idp.persistentId.sourceAttribute}" />
 +        <BeanManagedConnection>shibboleth.MySQLDataSource</BeanManagedConnection>
 +    </DataConnector></file>
 +  * Bereits **bestehende persistentIDs** lassen Sie in der Datenbank bestehen, wie sie sind. Aus diesen persistentIDs werden dann zwar nicht standardkonforme SAML pairwise-ids gebildet. Wir gehen allerdings nicht davon aus, dass Service Provider, die die pairwise-id entgegennehmen, prüfen, ob der Wert vor dem Scope standardkonform ist.
 +  * Übermitteln Sie für die pairwise-id den Wert, der persistentID **mit Scope**.
  
 +{{tag>idp4 tutorial persistentid storage datenbank session included-in-ansible}}
  • Zuletzt geändert: vor 4 Jahren