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:shibidp3userdepro [2019/08/28 09:24] Wolfgang Pempede:shibidp:config-deprovisionierung [2022/01/14 16:44] (aktuell) Wolfgang Pempe
Zeile 1: Zeile 1:
 ~~NOTOC~~ ~~NOTOC~~
 +
 ====== User Deprovisionierung via Attribute Query ====== ====== User Deprovisionierung via Attribute Query ======
 +
 +<callout color="#ff9900" title="Archiv">
 +Dieser Artikel ist ein Community-Beitrag für Shibboleth IdP 3.x. Es ist unklar, ob er für Shibboleth IdP 4.x so noch gilt.
 +</callout>
 +
 {{INLINETOC 2}} {{INLINETOC 2}}
  
-=====Einleitung=====+===== Einleitung =====
  
 Dies ist **keine fertige Schritt für Schritt Anleitung** wie man eine "shibbolisierte" Webanwendung (die Daten über Ihre Nutzer speichert) bereinigt, sondern die aufgeführten Punkte sollen lediglich als Gedankenanstoß dienen, wie man das Thema User Deprovisionierung angehen kann und was es zu beachten gilt. Dies ist **keine fertige Schritt für Schritt Anleitung** wie man eine "shibbolisierte" Webanwendung (die Daten über Ihre Nutzer speichert) bereinigt, sondern die aufgeführten Punkte sollen lediglich als Gedankenanstoß dienen, wie man das Thema User Deprovisionierung angehen kann und was es zu beachten gilt.
Zeile 10: Zeile 16:
 (Ausgenommen: man hat seinen Dienst noch über eine weitere Schnittstelle an das eigene IDM-System angeschlossen) (Ausgenommen: man hat seinen Dienst noch über eine weitere Schnittstelle an das eigene IDM-System angeschlossen)
  
-=====Lösungsansätze=====+===== Lösungsansätze =====
  
 Also wie entscheiden wir nun ob ein Nutzer noch existiert oder nicht?\\ Also wie entscheiden wir nun ob ein Nutzer noch existiert oder nicht?\\
 Überlegen wir mal kurz welche Möglichkeiten sich uns bieten, wenn wir nun "alte" Nutzer identifizieren und sperren oder gar entfernen wollen: Überlegen wir mal kurz welche Möglichkeiten sich uns bieten, wenn wir nun "alte" Nutzer identifizieren und sperren oder gar entfernen wollen:
-   - Sperren und Löschen des Nutzers nach definierter Inaktivität dessen+ 
 +  - Sperren und Löschen des Nutzers nach definierter Inaktivität dessen
       * Positiv: einfachster Weg ohne die Notwendigkeit irgendwelcher Erweiterungen       * Positiv: einfachster Weg ohne die Notwendigkeit irgendwelcher Erweiterungen
       * Negativ: Nutzererfahren unschön wenn man nach längerer Inaktivität einen leeren Account vorfindet und/oder sich in regelmäßigen Abständen einloggen muss (eventuell vorher per Mail benachrichtigen?!)       * Negativ: Nutzererfahren unschön wenn man nach längerer Inaktivität einen leeren Account vorfindet und/oder sich in regelmäßigen Abständen einloggen muss (eventuell vorher per Mail benachrichtigen?!)
-   - Abfrage des IDM-Systems (regelmäßig oder nach definierter Inaktivität des Nutzers) über eine weitere Schnittstelle+  - Abfrage des IDM-Systems (regelmäßig oder nach definierter Inaktivität des Nutzers) über eine weitere Schnittstelle
       * Positiv: Nutzer wird nur gesperrt/gelöscht wenn er wirklich nicht mehr existiert       * Positiv: Nutzer wird nur gesperrt/gelöscht wenn er wirklich nicht mehr existiert
       * Negativ: größerer Aufwand durch Anbindung über weitere Schnittstelle (eventuell Probleme mit Datenschutz und anderen technischen Vorkehrungen etc.)       * Negativ: größerer Aufwand durch Anbindung über weitere Schnittstelle (eventuell Probleme mit Datenschutz und anderen technischen Vorkehrungen etc.)
-   - Abfrage des Shibboleth-IdP (regelmäßig oder nach definierter Inaktivität des Nutzers) via Attribute-Query+  - Abfrage des Shibboleth-IdP (regelmäßig oder nach definierter Inaktivität des Nutzers) via Attribute-Query
       * Positiv: Nutzung einer bereits existierenden Schnittstelle       * Positiv: Nutzung einer bereits existierenden Schnittstelle
       * Negativ: es sind teilweise Anpassungen am SP und/oder IDM nötig       * Negativ: es sind teilweise Anpassungen am SP und/oder IDM nötig
  
-=====Anforderungen an Queries=====+===== Anforderungen an Queries =====
  
-Betrachten wir die letzte Variante mit Hilfe des Shibboleth-eigenen Board-Mittels namens **Attribute-Query**.\\ +Betrachten wir die letzte Variante mit Hilfe des Shibboleth-eigenen Board-Mittels namens **Attribute-Query**. \\ Ursprünglich diente dieses Verfahren bei SAML1 der direkten Übertragung der Nutzer-Attribute zwischen IdP und SP über einen Backchannel. \\ Hier stellte der SP nach erfolgreichem Login des Nutzers eine separate Anfrage an den IdP, welcher alle Attribute über den Nutzer auslieferte, die beim heutigen SAML2 über den Frontchannel übergeben werden.
-Ursprünglich diente dieses Verfahren bei SAML1 der direkten Übertragung der Nutzer-Attribute zwischen IdP und SP über einen Backchannel.\\ +
-Hier stellte der SP nach erfolgreichem Login des Nutzers eine separate Anfrage an den IdP, welcher alle Attribute über den Nutzer auslieferte, die beim heutigen SAML2 über den Frontchannel übergeben werden.+
  
-Um solch einen Query stellen zu können muss der SP im Besitz eines gültigen **NameIdentifiers** sein, damit der IdP diesen Auflösen kann.\\ +Um solch einen Query stellen zu können muss der SP im Besitz eines gültigen **NameIdentifiers**  sein, damit der IdP diesen Auflösen kann. \\ Wenn ein SP einen Query zu einem beliebigen Zeitpunkt stellen möchte (unabhängig vom Vorhandensein eines Login-Contextes des Nutzers), so kommt hier lediglich die **"persistentId"**  in Frage. \\ Diese muss auf Seiten des IdP dazu in einer Datenbank gespeichert werden, damit Sie rückwärts aufgelöst werden kann.
-Wenn ein SP einen Query zu einem beliebigen Zeitpunkt stellen möchte (unabhängig vom Vorhandensein eines Login-Contextes des Nutzers), so kommt hier lediglich die **"persistentId"** in Frage.\\ +
-Diese muss auf Seiten des IdP dazu in einer Datenbank gespeichert werden, damit Sie rückwärts aufgelöst werden kann.+
  
 **Anforderungen** **Anforderungen**
-   * persistentId wird an SP ausgeliefert 
-   * persistentId wird auf IdP Seite gespeichert 
-   * persistentId wird auf SP Seite gespeichert 
-   * Nutzer hat sich wenigstens einmal am SP angemeldet 
-   * Attribute Query Profil ist für RelyingParty freigeschalten 
-   * SP hat Möglichkeit einen Query zu stellen 
-   * SP erreicht den IdP direkt (ohne Umweg/Redirect über den Browser des Client) 
-   * es wird wenigstens ein Attribut an den SP ausgeliefert 
  
-=====Queries stellen=====+  * persistentId wird an SP ausgeliefert 
 +  * persistentId wird auf IdP Seite gespeichert 
 +  * persistentId wird auf SP Seite gespeichert 
 +  * Nutzer hat sich wenigstens einmal am SP angemeldet 
 +  * Attribute Query Profil ist für RelyingParty freigeschalten 
 +  * SP hat Möglichkeit einen Query zu stellen 
 +  * SP erreicht den IdP direkt (ohne Umweg/Redirect über den Browser des Client) 
 +  * es wird wenigstens ein Attribut an den SP ausgeliefert 
 + 
 +===== Queries stellen =====
  
 Wie stellt man einen Query? Wie stellt man einen Query?
  
-Standardmäßig bringt der SP ein **"resolvertest"**-Skript mit.\\ +Standardmäßig bringt der SP ein **"resolvertest"**-Skript mit. \\ Dieses empfiehlt sich jedoch nur für einen initialen Test, um zu Prüfen ob alle Einstellungen passen und der Attribute Query korrekt beantwortet wird. \\ Für den Produktiv-Einsatz arbeitet es **zu langsam**!
-Dieses empfiehlt sich jedoch nur für einen initialen Test, um zu Prüfen ob alle Einstellungen passen und der Attribute Query korrekt beantwortet wird.\\ +
-Für den Produktiv-Einsatz arbeitet es **zu langsam**!+
  
 <code> <code>
Zeile 59: Zeile 61:
 # surname: Mustermann # surname: Mustermann
 # ... # ...
 +
 </code> </code>
  
Zeile 70: Zeile 73:
 # surname: Mustermann # surname: Mustermann
 # ... # ...
 +
 </code> </code>
  
-Will man nun vom SP aus automatisiert Anfragen stellen so empfiehlt es sich auf den **Attribute Handler** bzw. die [[https://bitbucket.org/PEOFIAMP/shibsp-plugin-attributequery-handler/|Erweiterung der Gakunin-Föderation]] zurückgreifen.+Will man nun vom SP aus automatisiert Anfragen stellenso existiert hierfür der. sog. Attribute Resolver Handler:
  
 <file xml /etc/shibboleth/shibboleth2.xml> <file xml /etc/shibboleth/shibboleth2.xml>
 <!-- ... --> <!-- ... -->
- <OutOfProcess> +    <OutOfProcess> 
- <Extensions> +            <Extensions> 
- <Library path="attributequery-handler.so" fatal="true"/> +                <Library path="plugins.so" fatal="true"/> 
- </Extensions> +            </Extensions> 
- </OutOfProcess>+    </OutOfProcess>
  
- <InProcess> +    <InProcess> 
- <Extensions> +            <Extensions> 
- <Library path="attributequery-handler-lite.so" fatal="true"/> +                <Library path="plugins-lite.so" fatal="true"/> 
- </Extensions> +         </Extensions> 
- </InProcess>+    </InProcess>
  
- <ApplicationDefaults...> +    <ApplicationDefaults...> 
- <Sessions...> +        <Sessions...> 
- <!-- ... --> +            <!-- ... --> 
- <Handler type="AttributeQuery" Location="/AttributeQuery" acl="127.0.0.1 ::1" /> +            <Handler type="AttributeResolver" Location="/AttributeResolver" acl="127.0.0.1 ::1" /> 
- <!-- ... --> +            <!-- ... --> 
- </Sessions> +        </Sessions> 
- <!-- ... --> +        <!-- ... --> 
- </ApplicationDefaults>+        <AttributeResolver type="Query" subjectMatch="true"/> 
 +        <!-- ... --> 
 +    </ApplicationDefaults>
 <!-- ... --> <!-- ... -->
 +
 +
 </file> </file>
  
-Vergessen Sie nicht den **"shibdneu zu starten**!\\ +**Vergessen Sie nicht, sowohl den ''shibd'' als auch den Webserver/httpd neu zu starten**! \\ Danach kann ein Aufruf z.B. direkt mit CURL durchgeführt werden.
-Danach kann ein Aufruf z.B. direkt mit CURL durchgeführt werden.+
  
 <code> <code>
Zeile 107: Zeile 114:
 Stichwort URLencoding!!! Stichwort URLencoding!!!
  
-# curl -k "https://your-sp.de/Shibboleth.sso/AttributeQuery?entityID=https://your-idp.de/idp/shibboleth" --data-urlencode "nameId=+9Blu1I8v96axDXHj01Gmpg36fM="+# curl -k "https://your-sp.de/Shibboleth.sso/AttributeResolver?entityID=https://your-idp.de/idp/shibboleth" --data-urlencode "nameId=+9Blu1I8v96axDXHj01Gmpg36fM=" 
 </code> </code>
  
-Alternativ kann dies auch mit Hilfe des mitgelieferten Python-Skriptes ausgeführt werden.+===== Verlässlichkeit von Queries =====
  
-<code> +Hat man seine ersten Queries erfolgreich gestellt, kommen schnell die Fragen auf\\ **Wann kann ich den Nutzer löschen?**  und **Wie verlässlich ist die Rückgabe?**
-# /etc/shibboleth/attributequery.py https://your-sp.de/Shibboleth.sso/AttributeQuery https://your-idp.de/idp/shibboleth +9Blu1I8v96axDXHj01Gmpg36fM= +
-</code>+
  
-=====Verlässlichkeit von Queries=====+Wenn wir davon ausgehen dass ein Query das gleiche Attribut-Set zurück liefert, wie ein normaler Login-Vorgang, dann sollte man den Nutzer löschen können, sobald eine **leere Menge**  zurück kommt. \\ Aber **ACHTUNG**!!! \\ Folgende Fallstricke können fälschlicherweise zu einem **leeren**  oder auch **nicht leeren**  Ergebnis führen:
  
-Hat man seine ersten Queries erfolgreich gestellt, kommen schnell die Fragen auf:\\ +**leeres Ergebnis**
-**Wann kann ich den Nutzer löschen?** und **Wie verlässlich ist die Rückgabe?**+
  
-Wenn wir davon ausgehen dass ein Query das gleiche Attribut-Set zurück liefert, wie ein normaler Login-Vorgang, dann sollte man den Nutzer löschen können, sobald eine **leere Menge** zurück kommt.\\ +  persistentId wurde falsch übergeben 
-Aber **ACHTUNG**!!!\\ +  persistentId existiert nicht auf Seiten des IdP 
-Folgende Fallstricke können fälschlicherweise zu einem **leeren** oder auch **nicht leeren** Ergebnis führen:+  persistentId wird auf Seiten des IdP generell nicht gespeichert 
 +  Nutzer ist nicht mehr im LDAP (obwohl noch im IDM vorhanden - Synchronisierungsproblem) 
 +  LDAP-Verbindung ist abgebrochen 
 +  Query ist fehlgeschlagen
  
-**leeres Ergebnis**\\ +**nicht leeres Ergebnis**
-   * persistentId wurde falsch übergeben +
-   * persistentId existiert nicht auf Seiten des IdP +
-   * persistentId wird auf Seiten des IdP generell nicht gespeichert +
-   * Nutzer ist nicht mehr im LDAP (obwohl noch im IDM vorhanden - Synchronisierungsproblem) +
-   * LDAP-Verbindung ist abgebrochen +
-   * Query ist fehlgeschlagen+
  
-**nicht leeres Ergebnis**\\ +  * Statische Attribute im Resolver liefern immer Werte (obwohl Nutzer nicht mehr existent) 
-   * Statische Attribute im Resolver liefern immer Werte (obwohl Nutzer nicht mehr existent) +  * Nutzer wurde im LDAP nicht entfernt (obwohl im IDM nicht mehr vorhanden - Synchronisierungsproblem) 
-   * Nutzer wurde im LDAP nicht entfernt (obwohl im IDM nicht mehr vorhanden - Synchronisierungsproblem) +  * Nutzer Passwort wurde im LDAP geändert (damit er sich nicht mehr einloggen kann)
-   * Nutzer Passwort wurde im LDAP geändert (damit er sich nicht mehr einloggen kann)+
  
-Prinzipiell kann behauptet werden, dass man einem **leeren** Ergebnis **nicht** trauen kann und sollte!\\ +Prinzipiell kann behauptet werden, dass man einem **leeren**  Ergebnis **nicht**  trauen kann und sollte! \\ Doch wie schließt man nun die diversen Fehler bei der Übertragung aus?
-Doch wie schließt man nun die diversen Fehler bei der Übertragung aus?+
  
-Sicherer wäre es, wenn man ein Attribut bekommt, was den Nutzerstatus abbildet und an Hand dessen man entscheidet, ob der Nutzer deaktiviert bzw. gelöscht werden kann.\\ +Sicherer wäre es, wenn man ein Attribut bekommt, was den Nutzerstatus abbildet und an Hand dessen man entscheidet, ob der Nutzer deaktiviert bzw. gelöscht werden kann. \\ Denn wenn man einen definierten Wert für das Attribut erhält kann man zumindest davon ausgehen, dass alles funktioniert hat und der Query erfolgreich abgearbeitet wurde und auch sonst keine Probleme bei der Abfrage des LDAP oder sonst irgendwo bei der Kommunikation zwischen den Systemen aufgetreten sind!
-Denn wenn man einen definierten Wert für das Attribut erhält kann man zumindest davon ausgehen, dass alles funktioniert hat und der Query erfolgreich abgearbeitet wurde und auch sonst keine Probleme bei der Abfrage des LDAP oder sonst irgendwo bei der Kommunikation zwischen den Systemen aufgetreten sind!+
  
-Um den LDAP nicht mit **Karteileichen** vollzumüllen, so wäre eine Möglichkeit die Struktur des LDAP wie folgt zu erweitern:+Um den LDAP nicht mit **Karteileichen**  vollzumüllen, so wäre eine Möglichkeit die Struktur des LDAP wie folgt zu erweitern:
  
-   * ou=users,dc=einrichtung,dc=de (nur aktive Nutzer) +  ''ou=users,dc=einrichtung,dc=de''  (nur aktive Nutzer) 
-   * ou=archive,dc=einrichtung,dc=de +  ''ou=archive,dc=einrichtung,dc=de'' 
-      * ou=users,ou=archive,dc=einrichtung,dc=de (nur archivierte Nutzer) +      * ''ou=users,ou=archive,dc=einrichtung,dc=de''  (nur archivierte Nutzer) 
-         * ou=disabled,ou=users,ou=archive,dc=einrichtung,dc=de (gelöscht, kann aber wieder angelegt werden) +        ''ou=disabled,ou=users,ou=archive,dc=einrichtung,dc=de''  (gelöscht, kann aber wieder angelegt werden) 
-         * ou=locked,ou=users,ou=archive,dc=einrichtung,dc=de (vorübergehend gesperrt, z.B. aus Sicherheitsgründen) +        ''ou=locked,ou=users,ou=archive,dc=einrichtung,dc=de''  (vorübergehend gesperrt, z.B. aus Sicherheitsgründen) 
-         * ou=deleted,ou=users,ou=archive,dc=einrichtung,dc=de (endgültig gelöschte Nutzer, falls die Identitäten noch gespeichert werden sollen, z.B. um sicherzustellen, dass User IDs nicht neu vergeben werden) +        ''ou=deleted,ou=users,ou=archive,dc=einrichtung,dc=de''  (endgültig gelöschte Nutzer, falls die Identitäten noch gespeichert werden sollen, z.B. um sicherzustellen, dass User IDs nicht neu vergeben werden) 
-Scheidet ein Nutzer aus oder muss z.B. auf Grund eines Sicherheitsvorfalls kurzfristig deaktiviert werden, so verschiebt man diesen zunächst nach "locked".\\ +Scheidet ein Nutzer aus oder muss z.B. auf Grund eines Sicherheitsvorfalls kurzfristig deaktiviert werden, so verschiebt man diesen zunächst nach ''locked''. \\ Damit kann er sich schon mal nicht mehr am IdP authentifizieren (da nicht mehr im baseDN). \\ Kommt der Nutzer nach x-Tagen nicht mehr zurück an die Einrichtung so kann man ihn dauerhaft löschen und nach ''disabled''  oder ''deleted''  verschieben.
-Damit kann er sich schon mal nicht mehr am IdP authentifizieren (da nicht mehr im baseDN).\\ +
-Kommt der Nutzer nach x-Tagen nicht mehr zurück an die Einrichtung so kann man ihn dauerhaft löschen und nach "disabledoder "deletedverschieben.+
  
-Generell reicht es zu, wenn die Einträge unter "ou=archivenur noch die "uid" beinhalten und nicht mehr alle Attribute. (das spart Speicher ^^)+Generell reicht es zu, wenn die Einträge unter ''ou=archive''  nur noch die "uid" beinhalten und nicht mehr alle Attribute. (das spart Speicher ^^)
  
-Jetzt definieren wir im IdP das Attribut [[https://wiki.refeds.org/display/STAN/SCHAC+Releases|schacUserStatus]], das den Status der betreffenden Identität abbilden soll:+Jetzt definieren wir im IdP das Attribut [[:de:common_attributes#a15|schacUserStatus]], das den Status der betreffenden Identität abbilden soll:
  
 Vokabular für schacUserStatus: Vokabular für schacUserStatus:
-  * Attributwert: ''urn:schac:userStatus:de:aai.dfn.de:idmStatus:STATUS'', wobei ''STATUS'' die folgenden Werte annehmen kann: 
-  * ''active'' (optional) (entspricht AD 'enabled') 
-  * ''locked'' (optional) (vorübergehend gesperrt, z.B. aus Sicherheitsgründen) 
-  * ''disabled'' (optional) (gelöscht, kann aber wieder angelegt werden) 
-  * ''deleted'' (mandatory) (Account und Benutzerinformationen gelöscht) 
  
 +  * Attributwert: ''urn:schac:userStatus:de:aai.dfn.de:idmStatus:STATUS'', wobei ''STATUS''  die folgenden Werte annehmen kann:
 +  * ''active''  (optional) (entspricht AD 'enabled')
 +  * ''locked''  (optional) (vorübergehend gesperrt, z.B. aus Sicherheitsgründen)
 +  * ''disabled''  (optional) (gelöscht, kann aber wieder angelegt werden)
 +  * ''deleted''  (mandatory) (Account und Benutzerinformationen gelöscht)
 <file xml conf/attribute-resolver.xml> <file xml conf/attribute-resolver.xml>
 <!--...--> <!--...-->
- <!-- look in dn of archiveLDAP for inactive or blocked --> +    <!-- look in dn of archiveLDAP for inactive or blocked --> 
- <!-- schacUserStatus --> +    <!-- schacUserStatus --> 
- <AttributeDefinition xsi:type="ScriptedAttribute" id="schacUserStatus"> +    <AttributeDefinition xsi:type="ScriptedAttribute" id="schacUserStatus"> 
- <InputDataConnector ref="archiveLDAP" /> +        <InputDataConnector ref="archiveLDAP" /> 
- <DisplayName xml:lang="de">Benutzerstatus</DisplayName> +        <DisplayName xml:lang="de">Benutzerstatus</DisplayName> 
- <DisplayName xml:lang="en">Userstatus</DisplayName> +        <DisplayName xml:lang="en">Userstatus</DisplayName> 
- <DisplayDescription xml:lang="de">Status eines Benutzers für einen Dienst</DisplayDescription> +        <DisplayDescription xml:lang="de">Status eines Benutzers für einen Dienst</DisplayDescription> 
- <DisplayDescription xml:lang="en">set of status of a person as user of services</DisplayDescription> +        <DisplayDescription xml:lang="en">set of status of a person as user of services</DisplayDescription> 
- <AttributeEncoder xsi:type="SAML1String" name="urn:mace:terena.org:schac:attribut-def:schacUserStatus" /> +        <AttributeEncoder xsi:type="SAML1String" name="urn:mace:terena.org:schac:attribut-def:schacUserStatus" /> 
- <AttributeEncoder xsi:type="SAML2String" name="urn:oid:1.3.6.1.4.1.25178.1.2.19" friendlyName="schacUserStatus" /> +        <AttributeEncoder xsi:type="SAML2String" name="urn:oid:1.3.6.1.4.1.25178.1.2.19" friendlyName="schacUserStatus" /> 
- <Script> +        <Script> 
- <![CDATA[ +            <![CDATA[ 
- if (typeof entryDN != "undefined" && entryDN.getValues().size() > 0) { +                if (typeof entryDN != "undefined" && entryDN.getValues().size()> 0) { 
- var prefix = "urn:schac:userStatus:de:aai.dfn.de:"; +                    var prefix = "urn:schac:userStatus:de:aai.dfn.de:"; 
- var disabled= "ou=disabled,ou=users,ou=archive,dc=einrichtung,dc=de"; +                    var disabled= "ou=disabled,ou=users,ou=archive,dc=einrichtung,dc=de"; 
- var locked  = "ou=locked,ou=users,ou=archive,dc=einrichtung,dc=de";+                    var locked  = "ou=locked,ou=users,ou=archive,dc=einrichtung,dc=de";
                                         var deleted = "ou=deleted,ou=users,ou=archive,dc=einrichtung,dc=de";                                         var deleted = "ou=deleted,ou=users,ou=archive,dc=einrichtung,dc=de";
  
- for (i=0; i<entryDN.getValues().size(); i++) { +                    for (i=0; i<entryDN.getValues().size(); i++) { 
- var tmp = entryDN.getValues().get(i);+                        var tmp = entryDN.getValues().get(i);
  
- if (tmp.endsWith(disabled)) { +                        if (tmp.endsWith(disabled)) { 
- schacUserStatus.addValue(prefix + "idmStatus:disabled"); +                            schacUserStatus.addValue(prefix + "idmStatus:disabled"); 
- +                        
- else if (tmp.endsWith(locked)) { +                        else if (tmp.endsWith(locked)) { 
- schacUserStatus.addValue(prefix + "idmStatus:locked"); +                            schacUserStatus.addValue(prefix + "idmStatus:locked"); 
- +                        
- else if (tmp.endsWith(deleted)) { +                        else if (tmp.endsWith(deleted)) { 
- schacUserStatus.addValue(prefix + "idmStatus:deleted"); +                            schacUserStatus.addValue(prefix + "idmStatus:deleted"); 
- +                        
- else { +                        else { 
- schacUserStatus.addValue(prefix + "idmStatus:active"); +                            schacUserStatus.addValue(prefix + "idmStatus:active"); 
- +                        
- +                    
- +                
- ]]> +            ]]> 
- </Script> +        </Script> 
- </AttributeDefinition>+    </AttributeDefinition>
  
- <DataConnector id="archiveLDAP" xsi:type="LDAPDirectory" +    <DataConnector id="archiveLDAP" xsi:type="LDAPDirectory" 
- ldapURL="%{idp.attribute.resolver.LDAP.ldapURL}" +        ldapURL="%{idp.attribute.resolver.LDAP.ldapURL}" 
- baseDN="%{idp.attribute.resolver.LDAP.archiveDN}"  +        baseDN="%{idp.attribute.resolver.LDAP.archiveDN}" 
- principal="%{idp.attribute.resolver.LDAP.bindDN}" +        principal="%{idp.attribute.resolver.LDAP.bindDN}" 
- principalCredential="%{idp.attribute.resolver.LDAP.bindDNCredential}" +        principalCredential="%{idp.attribute.resolver.LDAP.bindDNCredential}" 
- searchScope="SUBTREE" +        searchScope="SUBTREE" 
- maxResultSize="0" +        maxResultSize="0" 
- useStartTLS="%{idp.attribute.resolver.LDAP.useStartTLS}">+        useStartTLS="%{idp.attribute.resolver.LDAP.useStartTLS}">
  
- <FilterTemplate> +        <FilterTemplate> 
- <![CDATA[ +            <![CDATA[ 
- %{idp.attribute.resolver.LDAP.archiveSearchFilter} +                %{idp.attribute.resolver.LDAP.archiveSearchFilter} 
- ]]> +            ]]> 
- </FilterTemplate> +        </FilterTemplate> 
- </DataConnector>+    </DataConnector>
 <!--...--> <!--...-->
 +
 +
 </file> </file>
  
 <file properties conf/ldap.properties> <file properties conf/ldap.properties>
 <!--...--> <!--...-->
- idp.attribute.resolver.LDAP.archiveDN           = ou=archive,dc=einrichtung,dc=de +    idp.attribute.resolver.LDAP.archiveDN           = ou=archive,dc=einrichtung,dc=de 
- idp.attribute.resolver.LDAP.archiveSearchFilter = (uid=$requestContext.principalName)+    idp.attribute.resolver.LDAP.archiveSearchFilter = (uid=$requestContext.principalName)
 <!--...--> <!--...-->
 +
 +
 </file> </file>
  
 <file xml conf/attribute-filter.xml> <file xml conf/attribute-filter.xml>
 <!--...--> <!--...-->
- <AttributeRule attributeID="schacUserStatus"> +    <AttributeRule attributeID="schacUserStatus"> 
- <PermitValueRule xsi:type="ANY" /> +        <PermitValueRule xsi:type="ANY" /> 
- </AttributeRule>+    </AttributeRule>
 <!--...--> <!--...-->
 +
 +
 </file> </file>
  
-Bekommt ein SP nun bei einem Query einen der folgenden Werte, so kann er den Nutzer verlässlich sperren oder gar löschen.\\ +Bekommt ein SP nun bei einem Query einen der folgenden Werte, so kann er den Nutzer verlässlich sperren oder gar löschen. 
-   * ''urn:schac:userStatus:de:aai.dfn.de:idmStatus:disabled'' + 
-   * ''urn:schac:userStatus:de:aai.dfn.de:idmStatus:locked'' +  * ''urn:schac:userStatus:de:aai.dfn.de:idmStatus:disabled'' 
-   * ''urn:schac:userStatus:de:aai.dfn.de:idmStatus:deleted'' +  * ''urn:schac:userStatus:de:aai.dfn.de:idmStatus:locked'' 
-     +  * ''urn:schac:userStatus:de:aai.dfn.de:idmStatus:deleted'' 
-=====Queries einschränken=====+  * 
 + 
 +Als Beispiel für eine Attribute Query, die ein solches Attribut liefert, kann dieser URL genutzt werden: \\ [[https://testsp3.aai.dfn.de/Shibboleth.sso/AttributeResolver?entityID=https://testidp.aai.dfn.de/idp/shibboleth&nameId=MCE6NXEQ3FC3PUKY4M75EYCOWN4TGKBH&format=urn:oasis:names:tc:SAML:2.0:nameid-format:persistent|https://testsp3.aai.dfn.de/Shibboleth.sso/AttributeResolver?entityID=https://testidp.aai.dfn.de/idp/shibboleth&nameId=MCE6NXEQ3FC3PUKY4M75EYCOWN4TGKBH&format=urn:oasis:names:tc:SAML:2.0:nameid-format:persistent]] \\ 
 +(zuvor bitte bei der DFN-AAI Hotline Bescheid sagen, damit die ACL für diesen Handler entsprechend erweitert wird) 
 + 
 +===== Queries einschränken =====
  
 Wer darf eigentlich Queries stellen? Wer darf eigentlich Queries stellen?
  
-Da Queries nur mit Angabe der persistentId funktionieren, so kann man per RelyingParty-Config einschränken, dass nur die SPs Queries stellen dürfen für die auch die persistentId freigegeben ist.\\ +Da Queries nur mit Angabe der persistentId funktionieren, so kann man per RelyingParty-Config einschränken, dass nur die SPs Queries stellen dürfen für die auch die persistentId freigegeben ist. \\ Dies lässt sich unter Angabe einer [[de:shibidp:config-activation-condition|Activation Condition]] simpel lösen. \\ 
-Dies lässt sich unter Angabe einer [[de:shibidp3activationcondition|Activation Condition]] simpel lösen.\\ +**ACHTUNG:**  Diese Einstellung ist nur zu empfehlen, wenn **keine SAML1 SPs**  mehr bedient werden!!!
-**ACHTUNG:** Diese Einstellung ist nur zu empfehlen, wenn **keine SAML1 SPs** mehr bedient werden!!!+
  
 <file xml conf/relying-party.xml> <file xml conf/relying-party.xml>
 <!--...--> <!--...-->
- <bean id="shibboleth.DefaultRelyingParty" parent="RelyingParty"> +    <bean id="shibboleth.DefaultRelyingParty" parent="RelyingParty"> 
- <property name="profileConfigurations"> +        <property name="profileConfigurations"> 
- <list> +            <list> 
- <bean parent="SAML2.SSO" p:postAuthenticationFlows="#{{'attribute-release'}}" p:nameIDFormatPrecedence="#{{'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'}}" /> +                <bean parent="SAML2.SSO" p:postAuthenticationFlows="#{{'attribute-release'}}" p:nameIDFormatPrecedence="#{{'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'}}" /> 
- <ref bean="SAML2.Logout" /> +                <ref bean="SAML2.Logout" /> 
- <ref bean="SAML2.ArtifactResolution" /> +                <ref bean="SAML2.ArtifactResolution" /> 
- </list> +            </list> 
- </property> +        </property> 
- </bean>+    </bean>
  
- <util:list id="shibboleth.RelyingPartyOverrides"> +    <util:list id="shibboleth.RelyingPartyOverrides"> 
- <bean parent="RelyingParty" p:activationCondition-ref="SP-consumes-persistentId"> +        <bean parent="RelyingParty" p:activationCondition-ref="SP-consumes-persistentId"> 
- <property name="profileConfigurations"> +            <property name="profileConfigurations"> 
- <list> +                <list> 
- <bean parent="SAML2.SSO" p:postAuthenticationFlows="#{{'attribute-release'}}" p:nameIDFormatPrecedence="#{{'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'}}" /> +                    <bean parent="SAML2.SSO" p:postAuthenticationFlows="#{{'attribute-release'}}" p:nameIDFormatPrecedence="#{{'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'}}" /> 
- <ref bean="SAML2.Logout" /> +                    <ref bean="SAML2.Logout" /> 
- <ref bean="SAML2.AttributeQuery" /> +                    <ref bean="SAML2.AttributeQuery" /> 
- <ref bean="SAML2.ArtifactResolution" /> +                    <ref bean="SAML2.ArtifactResolution" /> 
- </list> +                </list> 
- </property> +            </property> 
- </bean> +        </bean> 
- </util:list>+    </util:list>
 <!--...--> <!--...-->
 +
 +
 </file> </file>
  
 <file xml conf/activation-conditions.xml> <file xml conf/activation-conditions.xml>
 <!--...--> <!--...-->
- <bean id="SP-consumes-persistentId" parent="shibboleth.Conditions.RelyingPartyId"> +    <bean id="SP-consumes-persistentId" parent="shibboleth.Conditions.RelyingPartyId"> 
- <constructor-arg name="candidates"> +        <constructor-arg name="candidates"> 
- <list> +            <list> 
- <value>https://your-sp.de/shibboleth</value> +                <value>https://your-sp.de/shibboleth</value> 
- <value>https://another-sp.de/shibboleth</value> +                <value>https://another-sp.de/shibboleth</value> 
- </list> +            </list> 
- </constructor-arg> +        </constructor-arg> 
- </bean>+    </bean>
 <!--...--> <!--...-->
 +
 +
 </file> </file>
  
-Wozu sollen Queries genutzt werden?\\ +Wozu sollen Queries genutzt werden?
-   * User-Synchronisierung +
-   * User-Deprovisionierung+
  
-Möchte man via Query Nutzerdaten synchron halten, so sind keine weiteren Einstellungen nötig.\\ +  * User-Synchronisierung 
-Es empfiehlt sich jedoch im Vorfeld mit dem **Datenschutzbeauftragten** dieses Vorgehen im Vorfeld zu besprechen, da hier **ohne Einverständnis** des Nutzers **personenbezogene Daten*ausgetauscht werden!!!+  User-Deprovisionierung
  
-Will man Queries ausschließlich zur User-Deprovisionierung benutzen, so kann man sämtliche anderen Attribute für diesen Kanal deaktivieren.\\ +Möchte man via Query Nutzerdaten synchron halten, so sind keine weiteren Einstellungen nötig. \\ Es empfiehlt sich jedoch im Vorfeld mit dem **Datenschutzbeauftragten**  dieses Vorgehen im Vorfeld zu besprechen, da hier **ohne Einverständnis**  des Nutzers **personenbezogene Daten**  ausgetauscht werden!!!
-Dies bringt unter anderem folgende Vorteile mit sich+
-   Minimierung der openLDAP Abfragen +
-   Lastminimierung bei scripted Attributes +
-   Datenschutz + Datensparsamkeit!+
  
-Dazu laden wir uns zunächst folgende JAR-File [[https://cloudstore.zih.tu-dresden.de/index.php/s/RrhJkwDwZOQoKRm|idp-predicate-impl-1.0.0.jar]] herunter und legen diese unter "./edit-webapp/WEB-INF/lib/" ab.\\ +Will man Queries ausschließlich zur User-Deprovisionierung benutzen, so kann man sämtliche anderen Attribute für diesen Kanal deaktivieren. \\ Dies bringt unter anderem folgende Vorteile mit sich:
-Anschließend den IdP neubauen.+
  
 +  * Minimierung der openLDAP Abfragen
 +  * Lastminimierung bei scripted Attributes
 +  * Datenschutz + Datensparsamkeit!
 +
 +Dazu laden wir uns zunächst folgende JAR-File [[https://box.fu-berlin.de/s/tMzEosxrAxp8wtC|idp-predicate-impl-1.0.0.jar]] herunter und legen diese unter "./edit-webapp/WEB-INF/lib/" ab. \\
 +Anschließend den IdP neubauen.
 <code> <code>
 +
 # ./bin/build.sh # ./bin/build.sh
 +
 </code> </code>
  
-Danke noch mal an Steffen Hofmann (FU Berlin), der diese Datei zur Verfügung gestellt hat.\\ +Danke noch mal an Steffen Hofmann (FU Berlin), der diese Datei zur Verfügung gestellt hat. \\ Mit Hilfe des **enthaltenen Predicate**  ist es uns möglich eine Entscheidung zu treffen ob es sich um einen **Attribute-Query**  handelt oder nicht. \\ Darauf aufbauend erstellen wir uns beliebige **Activation Conditions**, um die Erstellung und **Freigabe von Attributen**  zu steuern.
-Mit Hilfe des **enthaltenen Predicate** ist es uns möglich eine Entscheidung zu treffen ob es sich um einen **Attribute-Query** handelt oder nicht.\\ +
-Darauf aufbauend erstellen wir uns beliebige **Activation Conditions**, um die Erstellung und **Freigabe von Attributen** zu steuern.+
  
 <file xml conf/activation-conditions.xml> <file xml conf/activation-conditions.xml>
 <!--...--> <!--...-->
- <!-- condition is true if request is NOT an attribute-query --> +    <!-- condition is true if request is NOT an attribute-query --> 
- <bean id="no-query" parent="shibboleth.Conditions.NOT"> +    <bean id="no-query" parent="shibboleth.Conditions.NOT"> 
- <constructor-arg> +        <constructor-arg> 
- <list> +            <list> 
- <ref bean="RequestedAttributeQueryProfileIdPredicate" /> +                <ref bean="RequestedAttributeQueryProfileIdPredicate" /> 
- </list> +            </list> 
- </constructor-arg> +        </constructor-arg> 
- </bean>+    </bean>
  
- <!-- condition is true if request is NOT an attribute-query and if sp is one of the following --> +    <!-- condition is true if request is NOT an attribute-query and if sp is one of the following --> 
- <bean id="SP-consumes-isMemberOf" parent="shibboleth.Conditions.AND"> +    <bean id="SP-consumes-isMemberOf" parent="shibboleth.Conditions.AND"> 
- <constructor-arg> +        <constructor-arg> 
- <list> +            <list> 
- <ref bean="no-query" /> +                <ref bean="no-query" /> 
- <bean parent="shibboleth.Conditions.RelyingPartyId"> +                <bean parent="shibboleth.Conditions.RelyingPartyId"> 
- <constructor-arg name="candidates"> +                    <constructor-arg name="candidates"> 
- <list> +                        <list> 
- <value>https://your-sp.de/shibboleth</value> +                            <value>https://your-sp.de/shibboleth</value> 
- <value>https://another-sp.de/shibboleth</value> +                            <value>https://another-sp.de/shibboleth</value> 
- </list> +                        </list> 
- </constructor-arg> +                    </constructor-arg> 
- </bean> +                </bean> 
- </list> +            </list> 
- </constructor-arg> +        </constructor-arg> 
- </bean>+    </bean>
  
- <!-- condition is true if request IS an attribute-query and if sp consumes the persistentId --> +    <!-- condition is true if request IS an attribute-query and if sp consumes the persistentId --> 
- <bean id="SP-consumes-schacUserStatus" parent="shibboleth.Conditions.AND"> +    <bean id="SP-consumes-schacUserStatus" parent="shibboleth.Conditions.AND"> 
- <constructor-arg> +        <constructor-arg> 
- <list> +            <list> 
- <ref bean="RequestedAttributeQueryProfileIdPredicate" /> +                <ref bean="RequestedAttributeQueryProfileIdPredicate" /> 
- <ref bean="SP-consumes-persistentId" /> +                <ref bean="SP-consumes-persistentId" /> 
- </list> +            </list> 
- </constructor-arg> +        </constructor-arg> 
- </bean>+    </bean>
 <!--...--> <!--...-->
 +
 +
 </file> </file>
  
-Nun aktivieren wir die Bedingungen im Resolver.\\ +Nun aktivieren wir die Bedingungen im Resolver. \\ Dadurch werden **normale**  Attribute **nur**  noch bei einem normalen Login gebaut und an den Filter weitergereicht werden, aber nicht bei einem Query. \\ Das **schacUserStatus**  Attribut hingegen wird **nur**  noch bei einem Query erstellt.
-Dadurch werden **normale** Attribute **nur** noch bei einem normalen Login gebaut und an den Filter weitergereicht werden, aber nicht bei einem Query.\\ +
-Das **schacUserStatus** Attribut hingegen wird **nur** noch bei einem Query erstellt.+
  
 <file xml conf/attribute-resolver.xml> <file xml conf/attribute-resolver.xml>
 <!--...--> <!--...-->
- # Die Angabe einer ActivationCondition an einem normalen Attribut führt leider nicht dazu, dass die LDAP-Abfragen nur gestellt werden, wenn der SP in der Condition steht +    # Die Angabe einer ActivationCondition an einem normalen Attribut führt leider nicht dazu, dass die LDAP-Abfragen nur gestellt werden, wenn der SP in der Condition steht 
- # Sondern: +    # Sondern: 
- # - Das Attribut wird erst gebaut (LDAP-Abfrage) und erst danach greift die Condition und regelt die Weitergabe des Attributs an die Filter +       - Das Attribut wird erst gebaut (LDAP-Abfrage) und erst danach greift die Condition und regelt die Weitergabe des Attributs an die Filter 
- # - Die Condition MUSS daher an die LDAP-Dependency (DataConnector) gehangen werden, um die Ausführung der LDAP-Anfragen zu steuern/vermeiden+       - Die Condition MUSS daher an die LDAP-Dependency (DataConnector) gehangen werden, um die Ausführung der LDAP-Anfragen zu steuern/vermeiden
  
- <AttributeDefinition xsi:type="Simple" id="uid"> +    <AttributeDefinition xsi:type="Simple" id="uid"> 
- <InputDataConnector ref="myLDAP" attributeNames="uid"/> +        <InputDataConnector ref="myLDAP" attributeNames="uid"/> 
- <!--...--> +        <!--...--> 
- </AttributeDefinition>+    </AttributeDefinition>
  
- <DataConnector id="myLDAP" xsi:type="LDAPDirectory" activationConditionRef="no-query" +    <DataConnector id="myLDAP" xsi:type="LDAPDirectory" activationConditionRef="no-query" 
- <!--...--> +        <!--...--> 
- </DataConnector>+    </DataConnector>
  
- # Bei Attributen, die zusätzliche Conditions erhalten sollen können diese direkt am Attribut referenziert werden+    # Bei Attributen, die zusätzliche Conditions erhalten sollen können diese direkt am Attribut referenziert werden
  
- <AttributeDefinition xsi:type="Simple" id="isMemberOf" activationConditionRef="SP-consumes-isMemberOf"> +    <AttributeDefinition xsi:type="Simple" id="isMemberOf" activationConditionRef="SP-consumes-isMemberOf"> 
- <InputDataConnector ref="groupLDAP" attributeNames="cn"/> +        <InputDataConnector ref="groupLDAP" attributeNames="cn"/> 
- <!--...--> +        <!--...--> 
- </AttributeDefinition>+    </AttributeDefinition>
  
- <DataConnector id="groupLDAP" xsi:type="LDAPDirectory" activationConditionRef="SP-consumes-isMemberOf" +    <DataConnector id="groupLDAP" xsi:type="LDAPDirectory" activationConditionRef="SP-consumes-isMemberOf" 
- <!--...--> +        <!--...--> 
- </DataConnector>+    </DataConnector>
  
- <AttributeDefinition xsi:type="ScriptedAttribute" id="schacUserStatus" activationConditionRef="SP-consumes-schacUserStatus"> +    <AttributeDefinition xsi:type="ScriptedAttribute" id="schacUserStatus" activationConditionRef="SP-consumes-schacUserStatus"> 
- <InputDataConnector ref="archiveLDAP" /> +        <InputDataConnector ref="archiveLDAP" /> 
- <!--...--> +        <!--...--> 
- </AttributeDefinition>+    </AttributeDefinition>
  
- <DataConnector id="archiveLDAP" xsi:type="LDAPDirectory" activationConditionRef="SP-consumes-schacUserStatus" +    <DataConnector id="archiveLDAP" xsi:type="LDAPDirectory" activationConditionRef="SP-consumes-schacUserStatus" 
- <!--...--> +        <!--...--> 
- </DataConnector>+    </DataConnector>
 <!--...--> <!--...-->
 +
 +
 </file> </file>
  
 Zusammenfassend hat man somit folgende Punkte realisiert: Zusammenfassend hat man somit folgende Punkte realisiert:
-   * attributeQueries sind nur für SPs freigeschalten, die laut relying-party.xml auch die persistentID beziehen (ohne diese ist eine Abfrage erst gar nicht möglich) 
-   * wer diese bezieht ist in der activation-conditions.xml unter der bean "SP-consumes-persistentId" definiert 
  
-   * bei einem query soll lediglich das attribut "schacUserStatus" (und eventuell die "affiliation"?) ausgelesen und ausgeliefert werden +  * attributeQueries sind nur für SPs freigeschalten, die laut relying-party.xml auch die persistentID beziehen (ohne diese ist eine Abfrage erst gar nicht möglich
-   * alle anderen attribute "nur" bei normalen logins (datenschutz und entlastung des ldap+  wer diese bezieht ist in der activation-conditions.xml unter der bean "SP-consumes-persistentId" definiert
-   die einschränkungen müssen in der attribute-resolver.xml mittels activationConditionRef realisiert werden+
  
-   * jeder dataConnector erhält eine condition, somit werden z.B. unnötige LDAP-Abfragen vorweg vermieden +  * bei einem query soll lediglich das attribut "schacUserStatus" (und eventuell die "affiliation"?) ausgelesen und ausgeliefert werden 
-   * jedes attribut welches nur von einem dataconnector abhängt braucht nicht unbedingt eine weitere condition +  alle anderen attribute "nur" bei normalen logins (datenschutz und entlastung des ldap
-   lediglich attribute die von keinem connector oder von anderen attributen (ohne connectorabhängen benötigen eine zusätzliche condition +  die einschränkungen müssen in der attribute-resolver.xml mittels activationConditionRef realisiert werden
-   teils verknüpfung mehrerer bedingungen bei den conditions da einige attribute z.B. nur an bestimmte SPs ausgeliefert werden+
  
-=====Wann / Wie oft Queries stellen=====+  * jeder dataConnector erhält eine condition, somit werden z.B. unnötige LDAP-Abfragen vorweg vermieden 
 +  * jedes attribut welches nur von einem dataconnector abhängt braucht nicht unbedingt eine weitere condition 
 +  * lediglich attribute die von keinem connector oder von anderen attributen (ohne connector) abhängen benötigen eine zusätzliche condition 
 +  * teils verknüpfung mehrerer bedingungen bei den conditions da einige attribute z.B. nur an bestimmte SPs ausgeliefert werden 
 + 
 +===== Wann / Wie oft Queries stellen =====
  
 Wann und wie oft sollten Queries gestellt werden? Wann und wie oft sollten Queries gestellt werden?
  
-Zunächst vorweg:\\ +Zunächst vorweg: \\ **Der SP ist verantwortlich**  dafür Sorge zu tragen, dass der IdP während seines Betriebes **nicht gestört**  wird, in dem er z.B. mit zu vielen Anfragen "bombardiert" wird!!!
-**Der SP ist verantwortlich** dafür Sorge zu tragen, dass der IdP während seines Betriebes **nicht gestört** wird, in dem er z.B. mit zu vielen Anfragen "bombardiert" wird!!!+
  
 Daher empfiehlt es sich Nutzer nur dann zu prüfen wenn folgende Bedingungen erfüllt sind: Daher empfiehlt es sich Nutzer nur dann zu prüfen wenn folgende Bedingungen erfüllt sind:
-   * letzter login > x Tage 
-   * letzte Prüfung > x Tage 
  
-Desweiteren sollte man **kleine Pausen zwischen einzelnen Queries** lassen, damit man als SP nicht Gefahr läuft z.B. durch Mechanismen wie Fail2Ban ausgesperrt zu werden.\\ +  letzter login> x Tage 
-Als Betreiber eines IdP ist es durchaus denkbar sich ähnlich wie im Thema [[de:shibidp3fail2ban|Abwehr Brute Force]] Gedanken zu machen um sich gegen zu viele Query-Anfragen zu schützen.+  letzte Prüfung> x Tage
  
-Am Besten man nutzt also eine Cachefile, in der man hinterlegt, wann der Nutzer das letzte Mal erfolgreich abgefragt wurde.\\ +Desweiteren sollte man **kleine Pausen zwischen einzelnen Queries**  lassen, damit man als SP nicht Gefahr läuft z.B. durch Mechanismen wie Fail2Ban ausgesperrt zu werden. \\ Als Betreiber eines IdP ist es durchaus denkbar sich ähnlich wie im Thema [[:de:shibidp:fail2ban|Abwehr Brute Force]] Gedanken zu machen um sich gegen zu viele Query-Anfragen zu schützen. 
-Es ist also **nicht notwendig** und **nicht emfehlenswert** jeden Nutzer jeden Tag zu prüfen!+ 
 +Am Besten man nutzt also eine Cachefile, in der man hinterlegt, wann der Nutzer das letzte Mal erfolgreich abgefragt wurde. \\ Es ist also **nicht notwendig**  und **nicht emfehlenswert**  jeden Nutzer jeden Tag zu prüfen!
  
 Vorteile: Vorteile:
-   * man minimiert die Anzahl an Anfragen (und damit die Last auf z.B. den IdP und den LDAP) 
-   * man vermeidet DOS-Attacken und eventuelle Sperrung via Fail2Ban 
-   * man gewährleistet, dass sich weiterhin Nutzer einloggen können 
  
-Alternativ besteht vielleicht die Möglichkeit einen **separaten IdP** aufzusetzen, der **ausschließlich** für die Abarbeitung von **Queries** zuständig ist.\\ +  * man minimiert die Anzahl an Anfragen (und damit die Last auf z.B. den IdP und den LDAP) 
-Dabei sollte sichergestellt sein, dass alle IdP-Server via **Datenbank-Replikation** den gleichen Datenbestand aufweisen!!!+  * man vermeidet DOS-Attacken und eventuelle Sperrung via Fail2Ban 
 +  * man gewährleistet, dass sich weiterhin Nutzer einloggen können 
 + 
 +Alternativ besteht vielleicht die Möglichkeit einen **separaten IdP**  aufzusetzen, der **ausschließlich**  für die Abarbeitung von **Queries**  zuständig ist. \\ Dabei sollte sichergestellt sein, dass alle IdP-Server via **Datenbank-Replikation**  den gleichen Datenbestand aufweisen!!!
  
 Denkbare Schwellwerte für Fail2Ban wären: maximal 50 Queries innerhalb von 10 Sekunden (nicht getestet und abhängig von der Menge der zu prüfenden Nutzer) Denkbare Schwellwerte für Fail2Ban wären: maximal 50 Queries innerhalb von 10 Sekunden (nicht getestet und abhängig von der Menge der zu prüfenden Nutzer)
  
-=====Links / Dokumentation===== +===== Links / Dokumentation ===== 
-   * https://www.switch.ch/aai/support/presentations/techupdate-2014/04_Account_Checking.pdf + 
-   https://bitbucket.org/PEOFIAMP/shibsp-plugin-attributequery-handler+  * [[de:shibidp:config-storage|Server-side Storage und persistent Id]] 
-   * https://wiki.shibboleth.net/confluence/display/IDP30/PersistentNameIDGenerationConfiguration#PersistentNameIDGenerationConfiguration-StoredIDs +  [[https://www.switch.ch/aai/support/presentations/techupdate-2014/04_Account_Checking.pdf|https://www.switch.ch/aai/support/presentations/techupdate-2014/04_Account_Checking.pdf]] 
-   * https://wiki.shibboleth.net/confluence/display/IDP30/SecurityAndNetworking#SecurityAndNetworking-PortsandConnectors +  [[https://shibboleth.atlassian.net/wiki/spaces/SP3/pages/2065334903/Attribute+Resolver+Handler|Shibboleth Wiki: Attribute Resolver Handler]] 
-   https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPAccountChecking+  * [[https://shibboleth.atlassian.net/wiki/spaces/SP3/pages/2065334902/resolvertest|Shibboleth Wiki: resolvertest]] 
 +  * [[https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631506/SecurityAndNetworking#Back-Channel-Support|Shibboleth Wiki: IdP 4 Backchannel Support]] 
 +  [[https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPAccountChecking|https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPAccountChecking]] 
 + 
 +{{tag>archiv fixme}} 
 + 
  • Zuletzt geändert: vor 5 Jahren