Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung |
de:shibidp:plugin-fudiscr [2024/07/12 20:11] – [Versionen] hofmann@fu-berlin.de | de:shibidp:plugin-fudiscr [2024/10/08 12:35] (aktuell) – [Hinweis zu älteren IdP-Konfigurationen] abalke@fu-berlin.de |
---|
| |
===== Allgemein ===== | ===== Allgemein ===== |
Das Plugin kann als weiterer Faktor für die Multi-Faktor-Authentifizierung (MFA) vom [[https://shibboleth.atlassian.net/wiki/spaces/IDP4/overview|Shibboleth Identity Provider (IdP)]] verwendet werden. | Das Plugin kann als weiterer Faktor für die Multi-Faktor-Authentifizierung (MFA) vom [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/overview|Shibboleth Identity Provider (IdP)]] verwendet werden. |
Es unterstützt tokenbasierte Authentifizierungen und folgt im Kern dem Challenge-Response-Pattern. | Es unterstützt Token basierte Authentifizierungen und folgt im Kern dem Challenge-Response-Pattern. |
Aus einem der vorherigen Faktoren in der MFA-Abfolge muss als Basis ein Benutzername ermittelt werden. | Aus einem der vorherigen Faktoren in der MFA-Abfolge wird als Basis ein Benutzername ermittelt. |
Ein häufiger Fall ist eine vorangestellte Authentifizierung mit Benutzer und Passwort gegen LDAP mit dem authn/Password-Flow. | Ein häufiger Fall ist eine vorangestellte Authentifizierung mit Benutzer und Passwort gegen LDAP mit dem authn/Password-Flow. |
| |
Es enthält auch selbst keine speziellen Algorithmen zur Validierung von Token. | Es enthält auch selbst keine speziellen Algorithmen zur Validierung von Token. |
Über ein generisches ChallengeResponseClientInterface kann ein Token-System angebunden werden. | Über ein generisches ChallengeResponseClientInterface kann ein Token-System angebunden werden. |
Das Plugin enthält bereits eine Implementierung dieses Interfaces für [[https://www.privacyidea.org/|privacyIDEA]]. | Das Plugin enthält bereits eine Implementierung dieses Interfaces für [[https://edumfa.io/|eduMFA]] und [[https://www.privacyidea.org/|privacyIDEA]]. |
Zudem ist eine Mockup-Implementierung für Tests enthalten. | Zudem ist eine rudimentäre Mockup-Implementierung für Tests enthalten. |
Eine externe Implementierung für Fortinet existiert auch bereits. | Eine externe Implementierung für [[https://www.fortinet.com/de/products/identity-access-management/fortiauthenticator|Fortinet]] existiert auch bereits. |
| |
Die primären Entwicklungsarbeiten wurden von Steffen Hofmann von der [[https://www.fu-berlin.de|Freien Universität Berlin]] durchgeführt. | Die primären Entwicklungsarbeiten wurden von Steffen Hofmann von der [[https://www.fu-berlin.de|Freien Universität Berlin]] durchgeführt. |
Er ist Mitarbeiter des Rechenzentrums [[https://www.zedat.fu-berlin.de|(FUB-IT Infrastruktur)]] und zuständig für den Bereich Identity Management. Das Identity Management System der Freien Universität Berlin trägt den Namen FUDIS (FU Directory and Identity Service). Aus diesem Grund wird für das **C**hallenge-**R**esponse-Plugin in Konfigurationsparametern u.a. das Kürzel fudiscr verwendet. | Er ist Mitarbeiter des Rechenzentrums [[https://www.zedat.fu-berlin.de|(FUB-IT)]] und zuständig für den Bereich Identity Management. Das Identity Management System der Freien Universität Berlin trägt den Namen FUDIS (FU Directory and Identity Service). Aus diesem Grund wird für das **C**hallenge-**R**esponse-Plugin in Konfigurationsparametern u.a. das Kürzel fudiscr verwendet. |
| |
Mit der Version 1.4.0 erfolgt eine Zusammenarbeit im Bereich FIDO2/WebAuthn mit der Hochschule München. Die Pflege des Plugins erfolgt mit dieser Version in Kooperation der [[https://www.fu-berlin.de|Freien Universität Berlin]] und der [[https://www.hm.edu|Hochschule München]]. | Mit den Versionen 1.4.0/2.0.0 erfolgt eine Zusammenarbeit im Bereich [[https://fidoalliance.org/passkeys/|Passkeys]] mit der [[https://www.hm.edu|Hochschule München]]. Das Plugin enthält ab diesen Versionen ein weiteres Authentifizierungsverfahren mit dem Namen fudispasskeys. Anstelle einer zweistufigen Authentifizierung aus z.B. Benutzernamen/Passwort und Token-Validierung mit fudiscr kann eine alleinige Authentifizierung mit [[https://fidoalliance.org/passkeys/|Passkeys]] durchgeführt werden. |
| |
===== Versionen ===== | |
^ Plugin-Version ^ IdP-Version ^ privacyIDEA-Version ^ Support-Level ^ | |
| 1.0.0 | min. 4.1.2 und < 4.3.0 | min. 3.7 | nicht mehr verwenden | | |
| 1.1.0 | min. 4.1.2 und < 4.3.0 | min. 3.7 | nicht mehr verwenden | | |
| 1.1.1 | min. 4.1.2 und < 4.3.0 | min. 3.7 | nicht mehr verwenden | | |
| 1.2.0 | min. 4.1.2 und < 4.3.0 | min. 3.7 | nicht mehr verwenden | | |
| 1.3.0 | min. 4.3.0 und < 5.0.0 | min. 3.7 | nicht mehr verwenden | | |
| 1.4.0 | min. 4.3.0 und < 5.0.0 | min. 3.9 | aktuell | | |
| 2.0.0 | min. 5.0.0 und < 5.1.0 | min. 3.9 | aktuell | | |
| 2.1.0 | min. 5.1.0 | min. 3.9 | aktuell | | |
===== Unterstütze Tokenverfahren aus privacyIDEA ===== | |
Aktuell werden die folgenden Tokenverfahren aus privacyIDEA ([[https://privacyidea.readthedocs.io/en/latest/tokens/tokentypes.html|Token types in privacyIDEA]]) unterstützt: | |
^ Tokenverfahren ^ Typbezeichnung im Plugin ^ min. Plugin-Version ^ Einschränkungen / Hinweise ^ | |
| Email | mail | 1.0.0 | | | |
| HOTP Token | hotp | 1.0.0 | | | |
| Indexed Secret Token | indexed_secret | 1.0.0 | | | |
| mOTP Token | motp | 1.0.0 | | | |
| Paper Token (PPR) | indexed_tan | 1.0.0 | | | |
| Questionnaire Token | question | 1.0.0 | Es darf nur eine Antwort per Richtlinie verlangt werden. | | |
| Registration | registration_code | 1.3.0 | | | |
| Remote | //referenzierter Tokentyp// | 1.3.0 | Nur referenzierte Token vom Typ //Email//, //HOTP Token//, //mOTP Token//, //Paper Token (PPR)//, //Registration//, //SMS Token//, //TAN Token, TOTP//, //Yubico// und //Yubikey// werden unterstützt. | | |
| SMS Token | sms | 1.0.0 | | | |
| TAN Token | tan | 1.0.0 | | | |
| TOTP | totp | 1.0.0 | | | |
| WebAuthn | web_authn | 1.2.0 | bei Version 1.2.0 nur mit Konfigurationsoption ''fudiscr.privacyidea.single_trigger_challenges=false'', ab Version 1.3.0 siehe [[#zusaetzliche_richtlinie_ab_fudiscr-version_version_130|Richtlinie und Event ab Version 1.3.0]] | | |
| Yubico | yubico_otp | 1.3.0 | | | |
| Yubikey | yubikey_aes | 1.3.0 | | | |
| |
===== Installation und Konfiguration ===== | ===== Versionen für den Shibboleth Identity Provider v4 ===== |
| <alert type="warning">End of life seit dem 01.09.2024</alert> |
| ^ Plugin-Version ^ IdP-Version ^ eduMFA-Version ^ privacyIDEA-Version ^ Support-Level ^ |
| | 1.0.0 | min. 4.1.2 und < 4.3.0 | N/A | min. 3.7 | nicht mehr verwenden | |
| | 1.1.0 | min. 4.1.2 und < 4.3.0 | N/A | min. 3.7 | nicht mehr verwenden | |
| | 1.1.1 | min. 4.1.2 und < 4.3.0 | N/A | min. 3.7 | nicht mehr verwenden | |
| | 1.2.0 | min. 4.1.2 und < 4.3.0 | N/A | min. 3.7 | nicht mehr verwenden | |
| | 1.3.0 | min. 4.3.0 und < 5.0.0 | N/A | min. 3.7 | nicht mehr verwenden | |
| | 1.4.0 | min. 4.3.0 und < 5.0.0 | min. 2.0.0 | min. 3.9.2 | nicht mehr verwenden | |
| |
==== Installation privacyIDEA ==== | ===== Versionen für den Shibboleth Identity Provider in der v5 ===== |
| ^ Plugin-Version ^ IdP-Version ^ eduMFA-Version ^ privacyIDEA-Version ^ Support-Level ^ |
| | 2.0.0 | min. 5.0.0 | min. 2.0.0 | min. 3.9.2 | nicht mehr verwenden | |
| | **2.1.0** | **min. 5.1.0** | **min. 2.0.0** | **min. 3.9.2** | **aktuell** | |
| ===== Unterstütze Token-Verfahren aus eduMFA und privacyIDEA ===== |
| Aktuell werden die folgenden Token-Verfahren aus eduMFA ([[https://edumfa.readthedocs.io/en/latest/tokens/tokentypes.html|Token types in eduMFA]]) und privacyIDEA ([[https://privacyidea.readthedocs.io/en/latest/tokens/tokentypes.html|Token types in privacyIDEA]]) unterstützt: |
| ^ Token-Verfahren ^ Typbezeichnung im Plugin ^ min. Plugin-Version ^ Einschränkungen / Hinweise ^ |
| | Email | mail | 1.0.0 | | |
| | HOTP Token | hotp | 1.0.0 | | |
| | Indexed Secret Token | indexed_secret | 1.0.0 | | |
| | mOTP Token | motp | 1.0.0 | | |
| | Paper Token (PPR) | indexed_tan | 1.0.0 | | |
| | Questionnaire Token | question | 1.0.0 | Es darf nur eine Antwort per Richtlinie verlangt werden. | |
| | Registration | registration_code | 1.3.0 | | |
| | Remote | //referenzierter Tokentyp// | 1.3.0 | Nur referenzierte Token vom Typ //Email//, //HOTP Token//, //mOTP Token//, //Paper Token (PPR)//, //Registration//, //SMS Token//, //TAN Token, TOTP//, //Yubico// und //Yubikey// werden unterstützt. | |
| | SMS Token | sms | 1.0.0 | | |
| | Spass | simple_pass_token | 1.4.0 / 2.0.0 | | |
| | TAN Token | tan | 1.0.0 | | |
| | TOTP | totp | 1.0.0 | | |
| | WebAuthn | web_authn | 1.2.0 | | |
| | Yubico | yubico_otp | 1.3.0 | | |
| | Yubikey | yubikey_aes | 1.3.0 | | |
| |
siehe [[https://gitlab.daasi.de/training/privacyidea|Installationsanleitung privacyIDEA von der DAASI GmbH]] | ===== Vorarbeiten im Token-Management-System ===== |
| |
==== Konfiguration privacyIDEA ==== | ==== eduMFA ==== |
| siehe [[de:shibidp:plugin-fudiscr:edumfa_setup|Installation und Konfiguration von eduMFA]] |
| |
=== Einrichtung eines Funktionsnutzers in privacyIDEA === | ==== privacyIDEA ==== |
| siehe [[de:shibidp:plugin-fudiscr:privacyidea_setup|Installation und Konfiguration von privayIDEA]] |
| |
Das Shibboleth-Plugin kommuniziert mit privacyIDEA über dessen API. Es werden drei Endpunkte verwendet: | ===== Installation ===== |
| |
* /token/ (Abrufen einer Liste von Tokens) | |
* /validate/triggerchallenge (Initiieren einer Token-Challenge) | |
* /validate/check (Überprüfen eines OTP ggf. in Kombination mit einer PIN) | |
| |
Ein Nutzer muss also über die Berechtigungen verfügen, die Aktionen, die bei Aufruf dieser Endpunkte ausgelöst werden, ausführen zu dürfen. Am besten sollte dieser Nutzer über keine weiteren Rechte verfügen. | |
\\ | |
\\ | |
== Anlegen eines Admin-Nutzers == | |
---- | |
**Achtung**: Wir gehen davon aus, das der initiale Admin-Supernutzer //admin// vorhanden ist. | |
Zunächst muss ein Admin-Nutzer für den Zugriff vom Identity Provider angelegt werden. Es empfiehlt sich, hierfür auch einen eigenen (administrativen) Realm anzulegen, um Berechtigungen für unterschiedliche Arten von Admin später besser trennen zu können. Der anzulegende Nutzer kann dann aus einer beliebigen externen Quelle kommen und über einen in privacyIDEA definierten Resolver importiert werden. | |
| |
Das Anlegen von Realms und Resolvern ist nicht Thema dieser Anleitung. Wir legen hier jedoch der Einfachheit und Anschaulichkeit wegen einen PrivacyIDEA-internen IdP-Admin-Nutzer an. | |
| |
<code> | |
pi-manage admin add idp-admin | |
</code> | |
| |
**Um die Anzahl an API-Anfragen zu reduzieren, sollte für den //idp-admin// anstelle von Benutzernamen und Passwort ein Token für den Zugriff erzeugt werden.** Dieser Token kann mit einer beliebigen Gültigkeitsdauer in Tagen (default 365) versehen werden. Das nachfolgende Beispiel legt eine Gültigkeitsdauer von zehn Jahren fest: | |
| |
<code> | |
pi-manage api createtoken -r admin -u idp-admin -d 3650 | |
</code> | |
\\ | |
== Vergeben der Berechtigungen == | |
---- | |
Die notwendigen Berechtigungen werden via Policy in privacyIDEA eingetragen. | |
| |
**Achtung**: Admins in privacyIDEA haben zu Beginn Rechte für alle Aktionen. | |
Dies gilt solange, wie keine Admin-Policy definiert ist. | |
Definiert man eine Policy im Scope 'admin', so gelten für alle Admins nur noch die den Policies eingetragenen Rechte. | |
Sollte es noch keine weitere Admin-Policy geben, sollte man daher darauf achten, sich nicht selbst aus dem Web-UI auszusperren. | |
| |
Zunächst wird mit der Richtlinien-Vorlage //superuser// die funktionserhaltende Richtlinie für den Admin-Supernutzer erstellt, und der Nutzer //admin// zugewiesen. | |
| |
Anschließend wird nun eine neue Policy für den Nutzer //idp-admin// erstellt. | |
| |
Hierfür wird eine neue Datei //idp-admin-policy// erstellt, welche die Parameter der Policy als Python-Dictionary enthält. Der Inhalt sollte wie folgt aussehen: | |
<file python idp-admin-policy> | |
{ 'policy': [ | |
{ | |
'action': {'tokenlist':True, 'triggerchallenge':True}, | |
'active': True, | |
'adminuser': ['idp-admin'], | |
'name': 'idp-admin-policy', | |
'scope': 'admin' | |
} | |
] | |
} | |
</file> | |
| |
Die Policy kann unter Nutzung dieser Datei erstellt werden: | |
<code> | |
pi-manage policy p_import -f idp-admin-policy | |
</code> | |
\\ | |
=== Zusätzliche Richtlinie ab fudiscr-Version Version 1.3.0 === | |
Das fudiscr-Plugin benötigt für bestimmte Tokenverfahren wie WebAuthn und zur Reduzierung von API-Anfragen das Recht, für ''/validate/triggerchallenge'' auf Tokentypen einschränken zu können. | |
| |
Hierfür wird eine neue Datei //idp-application-tokentype// erstellt, welche die Parameter der Policy als Python-Dictionary enthält. Der Inhalt sollte so aussehen: | |
<file python idp-application-tokentype> | |
{ 'policy': [ | |
{ | |
'action': { | |
'application_tokentype': True | |
}, | |
'active': True, | |
'name': 'idp-application-tokentype', | |
'scope': 'authorization' | |
} | |
] | |
} | |
</file> | |
| |
Die Policy kann unter Nutzung dieser Datei erstellt werden: | |
<code> | |
pi-manage policy p_import -f idp-application-tokentype | |
</code> | |
\\ | |
=== Event ab fudiscr-Version 1.3.0 === | |
Tests mit privcyIDEA haben ergeben, dass aufgrund eines Features/Bugs in Verbindung mit der zuvor genannten Policy //idp-application-tokentype// der Parameter ''webauthn_allowed_transports'' per Event gesetzt werden muss. | |
| |
Hierfür wird eine neue Datei //idp-webauthn-allowed-transports// erstellt, welche die Parameter des Events als Python-Dictionary enthält. Der Inhalt sollte so aussehen: | |
<file python idp-webauthn-allowed-transports> | |
{ 'event': [ | |
{ | |
'action': 'set', | |
'active': True, | |
'conditions': { | |
'tokentype': 'webauthn' | |
}, | |
'event': [ | |
'validate_triggerchallenge' | |
], | |
'handlermodule': 'RequestMangler', | |
'name': 'idp-webauthn-allowed-transports', | |
'options': { | |
'parameter': 'webauthn_allowed_transports', | |
'value': 'usb ble nfc internal' | |
}, | |
'position': 'pre' | |
} | |
] | |
} | |
</file> | |
| |
Das Event kann unter Nutzung dieser Datei erstellt werden: | |
<code> | |
pi-manage event e_import -f idp-webauthn-allowed-transports | |
</code> | |
| |
**Achtung:** Wenn per Policy der Wert ''webauthn_allowed_transports'' angepasst wird, dann sollte auch passend dazu das Event angepasst werden. | |
\\ | |
=== Weitere Konfigurationsempfehlung === | |
Damit möglichst viele WebAuthn-Token funktionieren und auch Passkey via QR-Code im Browser funktioniert, wird folgende weitere Richtlinie (Datei //webauthn-enrollment//) empfohlen: | |
| |
<file python webauthn-enrollment> | |
{ 'policy': [ | |
{ | |
'action': { | |
'webauthn_authenticator_attestation_form': 'indirect', | |
'webauthn_authenticator_attestation_level': 'none' | |
}, | |
'active': True, | |
'name': 'webauthn-enrollment', | |
'scope': 'enrollment', | |
} | |
] | |
} | |
</file> | |
| |
Die Policy kann unter Nutzung der Datei (//webauthn-enrollment//) erstellt werden: | |
<code> | |
pi-manage policy p_import -f webauthn-enrollment | |
</code> | |
| |
Die die für WebAuthn notwendigen Enrollment Parameter ''webauthn_relying_party_id'' und ''webauthn_relying_party_name'' können mit dieser oder einer separaten Richtlinie definiert werden. Allgemein gilt, dass die Domain des Identity Providers entweder identisch mit ''webauthn_relying_party_id'' oder eine Subdomain von ''webauthn_relying_party_id'' sein muss. (Es findet keine Vorabfilterung statt, ob die Domain des Identity Providers mit der ''webauthn_relying_party_id'' des WebAuthn-Token verträglich ist.) | |
| |
==== Aktivierung MFA-Modul ==== | ==== Aktivierung MFA-Modul ==== |
| |
| |
(siehe auch [[https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631610/MultiFactorAuthnConfiguration|Shibboleth-IdP MultiFactorAuthnConfiguration]]) | (siehe auch [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199505534/MultiFactorAuthnConfiguration|Shibboleth-IdP MultiFactorAuthnConfiguration]]) |
| \\ |
==== Installation fudiscr-Plugin ==== | ==== Installation fudiscr-Plugin ==== |
Die Installation sowie Updates erfolgen über den Shibboleth Plugin-Mechanismus (siehe offizielle Dokumentation [[https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1294074003/PluginInstallation|PluginInstallation]]) | Die Installation sowie Updates erfolgen über den Shibboleth Plugin-Mechanismus (siehe offizielle Dokumentation [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199500688/PluginInstallation|PluginInstallation]]) |
| |
**Achtung:** Der Shibboleth Identity Provider führt nach einer Plugin-Installation automatisch einen Neustart durch. | **Achtung:** Der Shibboleth Identity Provider führt nach einer Plugin-Installation automatisch einen Neustart durch. |
</code> | </code> |
| |
Zukünftige Updates werden automatisch mit dem folgendem Kommando installiert: | Zukünftige Updates werden automatisch mit dem folgendem Aufruf installiert: |
<code> | <code> |
%{idp.home}/bin/plugin.sh -u de.zedat.fudis.shibboleth.idp.plugin.authn.fudiscr | %{idp.home}/bin/plugin.sh -u de.zedat.fudis.shibboleth.idp.plugin.authn.fudiscr |
</code> | </code> |
\\ | \\ |
=== Installation der Testversion 1.4.0 === | |
Mit dem folgenden Aufruf kann die aktuelle Testversion des Plugins installiert und aktiviert werden: | |
<code> | |
%{idp.home}/bin/plugin.sh -i https://identity.fu-berlin.de/downloads/shibboleth/idp/plugins/authn/fudiscr/1.3.0/fudis-shibboleth-idp-plugin-authn-fudiscr-1.3.0.tar.gz | |
</code> | |
| |
Für ein Update auf die aktuelle Testversion ist folgender Aufruf zu verwenden: | ===== MFA-Konfiguration ===== |
<code> | |
%{idp.home}/bin/plugin.sh -u de.zedat.fudis.shibboleth.idp.plugin.authn.fudiscr -fu 1.4.0 | |
</code> | |
| |
==== Konfiguration fudiscr-Plugin ==== | |
| |
=== Hinweis zu älteren IdP-Konfigurationen === | |
Wenn Sie eine IdP-Konfiguration von vor Version 4.1.0 weiterpflegen, achten Sie bitte darauf, dass die Datei ''%{idp.home}/conf/idp.properties'' zu Beginn die folgende Zeile enthält, damit automatisch alle ''.properties''-Dateien unterhalb des ''%{idp.home}/conf''-Ordners (wie z.B. ''%{idp.home}/conf/fudiscr.properties'') eingelesen werden. | |
<file properties> | |
idp.searchForProperties=true | |
</file> | |
\\ | |
=== Konfigurationsdateien === | |
Mit der Installation des fudiscr-Plugins wird die Konfigurationsdatei ''%{idp.home}/conf/authn/fudiscr.properties'' abgelegt. Änderungen in dieser Datei werden in der Regel erst mit einem Neustart des Identity Providers wirksam. | |
| |
== ab Version 1.3.0 == | |
Ab der Version 1.3.0 wird zusätzlich die Konfigurationsdatei ''%{idp.home}/conf/authn/fudiscr.xml'' abgelegt. Die in dieser Datei enthaltenen Konfigurations-Beans werden über den [[https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631674/ReloadableServices|ReloadableService]]-Mechanismus vom Shibboleth Identity Provider verwaltet (siehe auch [[https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631674/ReloadableServices|ReloadableServices]]). | |
| |
Der Service kann wie folgt neu geladen werden: | |
<code> | |
%{idp.home}/bin/reload-service.sh -id fudiscr.ConfigurationBeansService | |
</code> | |
| |
Alternativ kann der Reload durch direkten Aufruf der URL ausgelöst werden und vermeidet Fehler durch den Wrapper in ''relaod-service.sh''. | |
<code> | |
GET http(s)://[idp-base-url]/idp/profile/admin/reload-service?id=fudiscr.ConfigurationBeansService | |
</code> | |
| |
Analog zu den Parametern für die anderen [[https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631674/ReloadableServices|ReloadableServices]] vom Shibboleth Identity Provider existieren die nachfolgenden für das fudiscr-Plugin: | |
<file properties> | |
fudiscr.service.failFast=false | |
fudiscr.service.checkInterval=PT0S | |
fudiscr.service.resources=fudiscr.ConfigurationResources | |
</file> | |
| |
Sollen Konfigurationsänderungen in ''%{idp.home}/conf/authn/fudiscr.xml'' automatisch geladen werden, so ist das Prüfintervall mit ''fudiscr.service.checkInterval'' zu setzen. Per Default (PT0S) ist die regelmäßige Prüfung der Veränderung des Zeitstempels von ''%{idp.home}/conf/authn/fudiscr.xml'' deaktiviert. | |
\\ | |
=== Allgemeine Konfigurationsoptionen === | |
Folgende allgemeine Konfigurationsoptionen können über die Konfigurationsdatei ''%{idp.home}/conf/authn/fudiscr.properties'' gesetzt werden. | |
^Option^Default-Wert^Beschreibung^ | |
|''fudiscr.username_realm_split_regex''|''@''|Aus einem vorherigen Faktor wird bei der Authentifizierung ein Benutzername erzeugt. Dieser kann auch einen Realm enthalten, z.B. //dummy@fu-berlin.de//. Mit dieser Option wird das Trennzeichen festgelegt, anhand dessen die Auftrennung in Benutzernamen und Realm erfolgt. Der Defaultwert ist ''@''| | |
|''fudiscr.default_users_realm''|//leer//|Sollte sich kein Realm aus dem Benutzernamen ergeben, so kann mit dieser Option ein Realm festegelegt werden, der bei Fehlen im fudiscr-Plugin ergänzt wird. In den meisten Fällen wird kein Realm benötigt, so dass per Default kein Realm ergänzt wird. | |
|''fudiscr.filter_tokens.type_exclude_regex''|//leer//|Mit dieser Option können Tokentypen für die Verwendung im fudiscr-Plugin ausgeschlossen werden. Z.B. werden mit //^totp$// alle TOTP-Token ignoriert. Per Default wird der Filter nicht verwendet. Die Regular Expression ist nicht definiert.| | |
|''fudiscr.filter_tokens.id_exclude_regex''|//leer//|Mit dieser Option können Token anhand ihrer ID/Seriennummer für die Verwendung im fudiscr-Plugin ausgeschlossen werden. Z.B. werden mit //^HOTP.*$// alle HOTP-Token ignoriert, die als Softwaretoken in privacyIDEA angelegt wurden und eine Seriennummer beginnend mit HOTP erhalten. Per Default wird der Filter nicht verwendet. Die Regular Expression ist nicht definiert.| | |
|''fudiscr.user_token_selection''|''none''|Diese Option legt fest, ob Token durch Nutzer*innen ausgewählt werden können. Mögliche Werte sind: ''none''=keine Auswahl, ''singleToken''=Auswahl eines einzelnen Token (anhand der ID/Seriennummer), ''multipleToken''=Auswahl mehrerer Token (anhand der Seriennummer), ''singleTokenTypeGroup''=Auswahl eines einzelnen Tokentyps (z.B. totp), ''singleTokenTypeGroup''=Auswahl mehrerer Tokentypen. Per Default (''none'') wird eine Challenge für alle aktive Token erzeugt.| | |
|''fudiscr.max_retries''|''10''|Anzahl an Fehlversuchen für die Validierung. Ist der Wert erreicht, wird die Validierung erfolglos beendet. Dieser Wert ist unabhängig von den erlaubten Fehlversuchen in privacyIDEA. Sollen ausschließlich die Fehlerzähler aus privacyIDEA wirken, so empfiehlt es sich, den Wert für ''fudiscr.max_retries'' passend zu erhöhen (> max. Failcounter in privacyIDEA).| | |
|''fudiscr.restart_allowed.max_retries_exceeded''|''shibboleth.Conditions.TRUE''|Dieses [[https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631700/PredefinedBeans|Predicate]] legt fest, ob ein Neustart der Authentifizierung im fudiscr-Plugin erlaubt ist, wenn ''fudiscr.max_retries'' erreicht ist.| | |
|''fudiscr.restart_allowed.selected_tokens_not_available''|''shibboleth.Conditions.TRUE''|Dieses [[https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631700/PredefinedBeans|Predicate]] legt fest, ob ein Neustart der Authentifizierung im fudiscr-Plugin erlaubt ist, wenn die durch Nutzer ausgewählten Token nicht mehr verfügbar sind (z.B. durch Sperrung in privacyIDEA).| | |
|''fudiscr.restart_allowed.within_response_page''|''shibboleth.Conditions.TRUE''|Dieses [[https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631700/PredefinedBeans|Predicate]] legt fest, ob ein Neustart der fudiscr-Authentifizierung über die Eingabeseite für die Response (OTP, TAN u.a.) erlaubt ist.|| | |
|''fudiscr.on_failed_restart_completely_mfa''|''shibboleth.Conditions.FALSE''|Dieses [[https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631700/PredefinedBeans|Predicate]] legt fest, ob bei einem Neustart der Authentifizieurung aus dem fudiscr-Plugin heraus nur der Faktor //fudiscr// im MFA-Flow (Default) oder die gesamte Authentifizierung neu gestartet wird. Gibt das [[https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631700/PredefinedBeans|Predicate]] ''TRUE'' zurück, werden also die Ergebnisse der vorherigen Faktoren zurückgesetzt. Es werden also Benutzername und Passwort u.a. erneut verlangt.| | |
|''fudiscr.result_with_username_principal''|''shibboleth.Conditions.TRUE''|Dieses [[https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631700/PredefinedBeans|Predicate]] legt fest, ob nach erfolgreicher Authentifizierung ein [[https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631602/AttributePostLoginC14NConfiguration|UsernamePrincipal]] dem Subject hinzugefügt wird. Per Default enthält das Authentifizierungsergebnis nach erfolgreicher Authentifizierung mit dem fudiscr-Plugin einen [[https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631602/AttributePostLoginC14NConfiguration|UsernamePrincipal]].| | |
|''fudiscr.result_with_realm_in_username_principal''|''shibboleth.Conditions.TRUE''|Ab fudiscr-Version 1.3.0: Wenn mit ''fudiscr.result_with_username_principal'' ein [[https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631602/AttributePostLoginC14NConfiguration|UsernamePrincipal]] erzeugt wird, dann legt dieses [[https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631700/PredefinedBeans|Predicate]] fest, ob der Realm enthalten ist. ''TRUE'' (default) erzeugt z.B. //dummy@fu-berlin.de//, ''FALSE'' nur //dummy// als Username.| | |
|''fudiscr.result_idp_attribute_principal_attribute_name''|//leer//|Wird mit dieser Option ein Attributname angeben, so wird ein [[https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631557/PrincipalNameAttributeDefinition|IdpAttributePrincipal]] mit diesem Attributnamen dem erfolgreichen Authentifizierungsergebnis des fudiscr-Plugins hinzugefügt. Der Attributwert enthält die ID/Seriennummer des Token, mit dem die Authentifizierung erfolgt ist.| | |
|''fudiscr.result_idp_attribute_principal_attribute_name_for_token_type''|//leer//|Ab fudiscr-Version 1.3.0: Wird mit dieser Option ein Attributname angeben, so wird ein [[https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631557/PrincipalNameAttributeDefinition|IdpAttributePrincipal]] mit diesem Attributnamen dem erfolgreichen Authentifizierungsergebnis des fudiscr-Plugins hinzugefügt. Der Attributwert enthält den Tokentyp des Token, mit dem die Authentifizierung erfolgt ist.| | |
| |
=== Konfigurationsoptionen für privacyIDEA === | |
^Option^Default-Wert^Beschreibung^ | |
|''fudiscr.privacyidea.base_uri''|//leer//|Basis-URL der privacyIDEA-API, z.B.// https://localhost //. Mit der fudiscr-Version 1.3.0 können mehrere URLs durch Leerzeichen getrennt angegeben werden.| | |
|''fudiscr.privacyidea.connection_strategy''|''ACTIVE_PASSIVE''|Erlaubt die fudiscr-Version in ''fudiscr.privacyidea.base_uri'' die Angabe mehrere privacyIDEA-Server, so kann mit dieser Option festgelegt werden, wie die Anfragen verteilt werden. Bei ''ACTIVE_PASSIVE'' (default) werden die URLs immer beginnend mit der ersten URL in Reihenfolge angefragt bis ein Server erfolgreich antwortet. Bei ''ROUND_ROBIN'' werden die URLs als zyklische Liste verwendet und bei jeder Anfrage wird die nächste URL aus der Liste benutzt.| | |
|''fudiscr.privacyidea.authorization_token''|//leer//|Authorization-Token aus vorherigem Anleitungsschritt für die Zugriffssteuerung auf die privacyIDEA-API.| | |
|''fudiscr.privacyidea.service_username''|//leer//|Username des Admin-Users; Alternative zu ''fudiscr.privacyidea.authorization_token'' oder zur Absicherung, falls Authorization-Token abläuft.| | |
|''fudiscr.privacyidea.service_realm''|//leer//|Realm des Admin-Users; Alternative zu ''fudiscr.privacyidea.authorization_token'' oder zur Absicherung, falls Authorization-Token abläuft.| | |
|''fudiscr.privacyidea.service_password''|//leer//|Passwort des Admin-Users; Alternative zu ''fudiscr.privacyidea.authorization_token'' oder zur Absicherung, falls Authorization-Token abläuft.| | |
|''fudiscr.privacyidea.check_connection_certificate''|''true''|Falls das Serverzertifikat vom API-Endpunkt nicht geprüft werden soll, kann der Wert auf ''false'' gesetzt werden.| | |
|''fudiscr.privacyidea.default_realm''|//leer//|Mit dieser Option kann festgelegt werden, ob ein Realm der API-Anfrage an privacyIDEA hinzugefügt wird, wenn in vorherigen Schritten kein Realm dem Nutzer zugeordnet ist. Der hier definierte Realm wird dem allgemeinen User-Objekt im fudiscr-Plugin nicht hinzugefügt!| | |
|''fudiscr.privacyidea.preferred_parameter_name''|//leer//|Wird mit dieser Option ein Name angegeben, so wird nach diesem Namen in den Token-Infos in privacyIDEA gesucht und versucht, den zugehörigen Wert als Boolean zu interpretieren. Sollte der Wert //true// ergeben, so wird der Token auf der eventuellen Auswahlseite der Token vorselektiert.| | |
|''fudiscr.privacyidea.relying_party_id_parameter_name''|//leer//|Wird mit dieser Option ein Name angegeben, so wird bei jeder Anfrage gegen die privacyIDEA-API die entityID des Service Providers als Parameter mit diesem Namen übergeben.| | |
|''fudiscr.privacyidea.user_agent_ip_address_parameter_name''|//leer//|Wird mit dieser Option ein Name angegeben, so wird bei jeder Anfrage gegen die privacyIDEA-API die IP-Adresse des Users als Parameter mit diesem Namen übergeben.| | |
|''fudiscr.privacyidea.singleton''|''true''|Gibt an, ob der vom fudiscr-Plugin verwendete //PrivacyIdeaChallengeResponseClient// nur einmal instanziiert wird. In manchen Anwendungsfällen kann es die Performance verbessern, wenn mehrere Instanzen zugelassen werden.| | |
|''fudiscr.privacyidea.with_additional_pin_response''|''false''|In privacyIDEA ist es möglich, neben dem one time password/code noch eine PIN zu verlangen. Wenn dieser Konfigurationsparameter auf ''true'' gesetzt ist, dann ergänzt das fudiscr-Plugin auf der Eingabeseite für die Response ein PIN-Feld. Nur für die Tokentypen //hotp//, //indexed_tan//, //registration_code//, //tan//, //totp// und //yubikey_otp// wird diese Funktionalität unterstützt. (Bis fudiscr-Version 1.2.0 wurde diese Option unter dem Namen ''fudiscr.with_additional_pin_response'' geführt.)| | |
|''fudiscr.privacyidea.single_trigger_challenges''|''true''|Dies Option existiert nur bis zur fudiscr-Version 1.2.0. Wird der Wert auf ''false'' gesetzt, wird über alle aktive Token der Nutzer*innen eine Challange ausgelöst und nicht (wie bei ''true'') eine separate Challenge pro Token. Wird WebAuthn mit mehreren aktiven WebAuthn-Token pro Nutzer in der fudiscr-Version 1.2.0 eingesetzt, so sollte der Wert auf ''false'' gesetzt werden.| | |
| |
**Hinweis**: In Abhängigkeit von der Konfigurationsweise des Shibboleth Identity Providers empfiehlt es sich, Token und Passwörter wie in ''fudiscr.privacyidea.authorization_token'' und ''fudiscr.privacyidea.service_password'' in geschützte/unversionierte Dateien wie ''%{idp.home}/credentials/secrets.properties'' auszulagern. | |
| |
=== Custom Token in privacyIDEA (ab Version 1.3.0) === | |
Für den Sonderfall, dass in privacyIDEA eigene Tokentypen implementiert werden, gibt es die Möglichkeit, diese auch über das fudiscr-Plugin zur Verfügung zu stellen. Dies ist aber nur möglich, wenn dieser neue Tokentyp keine Challenge erzeugt, die an Nutzer*innen zurückgegeben werden muss und wenn nur ein einfaches one time password verlangt wird. Der Token muss sich in der Nutzer-Interaktion also vergleichbar zu TOTP verhalten. | |
| |
In ''%{idp.home}/conf/global.xml'' kann hierfür die Bean ''fudiscr.privacyidea.CustomTokenTypesMap'' definiert werden: | |
<file xml> | |
<util:map id="fudiscr.privacyidea.CustomTokenTypesMap" map-class="java.util.HashMap" key-type="java.lang.String" value-type="java.lang.String"> | |
<entry key="custom_token_type_name_in_privacyidea" value="custom_token_type_name_in_fudiscr"/> | |
</util:map> | |
</file> | |
Die Map ''fudiscr.privacyidea.CustomTokenTypesMap'' kann auch dafür verwendet werden, das Mapping der Tokentypen auf die Bezeichnung in fudiscr anzupassen. Erlaubt sind nur 1:1-Beziehungen. | |
| |
Ergänzend entscheidet die Option ''fudiscr.privacyidea.replace_all_token_types_with_custom_map'' darüber, ob die Mappings aus ''fudiscr.privacyidea.CustomTokenTypesMap'' das Standardmapping ergänzen (''false'' //default//) oder vollständig ersetzen (''true''). | |
| |
=== Filterung von Token (ab Version 1.3.0) === | |
Ergänzend oder altenrativ zu den o.g. Konfigurationsoptionen ''fudiscr.filter_tokens.type_exclude_regex'' und ''fudiscr.filter_tokens.id_exclude_regex'' können weitere Ausschlussbedingungen für Token definiert werden. | |
| |
In ''%{idp.home}/conf/authn/fudiscr.xml'' kann mit ''fudiscr.ExcludeTokenPredicates'' eine Liste von Ausschlussfunktionen definiert werden. | |
<file xml> | |
<util:list id="fudiscr.ExcludeTokenPredicates"> | |
<ref bean="fudiscr.ExcludeTokenPredicate1"/> | |
<ref bean="fudiscr.ExcludeTokenPredicate2"/> | |
<!-- ... --> | |
</util:list> | |
</file> | |
| |
Die Ausschlussbedingungen können //Scripted// oder anhand von //Regular Expressions// bezogen auf Tokeneigenschaften formuliert werden. | |
| |
== Beispiel Scripted == | |
<file xml> | |
<util:list id="fudiscr.ExcludeTokenPredicates"> | |
<ref bean="fudiscr.ScriptedExcludeTokenPredicateExample1"/> | |
</util:list> | |
| |
<!-- Input1: profileRequestContext (org.opensaml.profile.context.ProfileRequestContext) --> | |
<!-- Input2: token (de.zedat.fudis.shibboleth.idp.plugin.authn.fudiscr.domain.Token) --> | |
<!-- Output -> java.lang.Boolean / boolean --> | |
<bean id="fudiscr.ScriptedExcludeTokenPredicateExample1" parent="fudiscr.Functions.ScriptedExcludeTokenPredicate" factory-method="inlineScript"> | |
<constructor-arg> | |
<value> | |
<![CDATA[ | |
// default is to keep the token | |
exclude = false; | |
| |
relyingPartyId = profileContext.getSubcontext("net.shibboleth.idp.profile.context.RelyingPartyContext").getRelyingPartyId(); | |
| |
// if the service provider is not 'https://portal.local/shibboleth', tokens that are of type 'registration_code' are excluded | |
if (!relyingPartyId.equals("https://portal.local/shibboleth") && token.getType().toString().equalsIgnoreCase("registration_code")) { | |
exclude = true; | |
} | |
| |
exclude; | |
]]> | |
</value> | |
</constructor-arg> | |
</bean> | |
</file> | |
In diesem Beispiel dürfen Notfallcodes (//registration_code//) nur für ein (Service-)Portal und sonst keinen anderen Service Provider verwendet werden. In diesem Szenario können z.B. Nutzer sich mit Hilfe der Notfallcodes wieder andere Tokenverfahren im (Service-)Portal einrichten bzw. freischalten. | |
== Beispiel mit Regular Expression == | |
<file xml> | |
<util:list id="fudiscr.ExcludeTokenPredicates"> | |
<ref bean="fudiscr.RegexExcludeTokenPredicateExample1"/> | |
<ref bean="fudiscr.RegexExcludeTokenPredicateExample2"/> | |
</util:list> | |
| |
<bean id="fudiscr.RegexExcludeTokenPredicateExample1" | |
class="de.zedat.fudis.shibboleth.idp.plugin.authn.fudiscr.function.impl.RegexExcludeTokenPropertiesPredicate" | |
c:propertyName="rollout_state" | |
c:excludePattern="^verify$"/> | |
<bean id="fudiscr.RegexExcludeTokenPredicateExample2" | |
class="de.zedat.fudis.shibboleth.idp.plugin.authn.fudiscr.function.impl.RegexExcludeTokenPropertiesPredicate" | |
c:propertyName="rollout_state" | |
c:excludePattern="^clientwait$"/> | |
</file> | |
In diesem Beispiel werden Token anhand einer Tokeneigenschaft herausgefiltert. In privacyIDEA können aktive Token existieren, die eine erste Validierung erfordern, bevor sie effektiv verwendet werden können. So soll z.B. erzwungen werden, dass Nutzer bei der Einrichtung eines TOTP-Token den QR-Code mit dem Authenticator einscannen und diesen Vorgang mit einem OTP bestätigen. Die Token besitzen bis zur Bestätigung die Eigenschaft //rollout_state// mit den Werten //verify// oder //clientwait//. Die in dem Beispiel verwendeten zwei Predicates lassen sich auch mit einem Predicate und der Regular Expression //^(clientwait|verify)$// abbilden. Es soll in dem Bespiel nur die Listeneigenschaft von ''fudiscr.ExcludeTokenPredicates'' verdeutlicht werden. | |
| |
(Mit dem Konstruktor-Parameter ''c:negateResult="true"'' kann das Ergbnis eines //ExcludeTokenPredicates// negiert werden.) | |
| |
=== Filterung von Token für die Funtkion fudiscr.UserHasTokenPredicate (ab Version 1.3.0) === | |
Mit der fudiscr-Version 1.1.0 wurde die Funktion ''fudiscr.UserHasAnyTokenPredicate'' eingeführt, die mit der Version 1.3.0 unter dem Namen ''fudiscr.UserHasTokenPredicate'' zur Verfügung steht. Diese Funktion dient dazu, um zu entscheiden, ob Nutzer generell schon für den zweiten Faktor bzw. für ein Tokenverfahren eingerichtet wurden. Während in fudiscr-Versionen vor 1.3.0 nur geprüft wurde, ob mindestens ein Token zu einem Nutzer egal in welchem Zustand existiert, können auch für diese Funktion Token äquivalent zur allgemeinen Filterung ausgeschlossen werden. Die zugehörige Bean-ID lautet hierfür ''fudiscr.UserHasTokenExcludeTokenPredicates''. | |
| |
Das vorherige Filterbeispiel lässt sich wie folgt übertragen: | |
== Beispiel mit Regular Expression == | |
<file xml> | |
<util:list id="fudiscr.UserHasTokenExcludeTokenPredicates"> | |
<ref bean="fudiscr.RegexExcludeTokenPredicateExample1/> | |
<ref bean="fudiscr.RegexExcludeTokenPredicateExample2"/> | |
</util:list> | |
</file> | |
Die Beans ''fudiscr.RegexExcludeTokenPredicateExample1'' und ''fudiscr.RegexExcludeTokenPredicateExample2'' können aus dem vorherigen Beispiel wiederverwendet werden. | |
| |
Wenn die allgemeine Tokenfilterung und die Filterung für die Funktion ''fudiscr.UserHasTokenPredicate'' identisch sind, kann auch ein Alias gesetzt werden: | |
<file xml> | |
<alias name="fudiscr.ExcludeTokenPredicates" alias="fudiscr.UserHasTokenExcludeTokenPredicates"/> | |
</file> | |
\\ | |
=== vorselektierte Token (ab Version 1.3.0) === | |
Äquivalent zu den Filtern ''fudiscr.ExcludeTokenPredicates'' und ''fudiscr.UserHasTokenExcludeTokenPredicates'' kann ein Filter definiert werden, der die bevorzugten Token eines Nutzers herausfiltert. Wird die Exclude-Filter-Liste ''fudiscr.PreferredExcludeTokenPredicates'' definiert, so werden initial nur die bevorzugten Token verwendet. Führt die Filterung dazu, dass alle Token ausgeschlossen werden, wird die Filterung zurückgesetzt. Sollte die Filterung die Ausgangsliste reduzieren, so wird dem Nutzer auf der Auswahlseite für die Token und der Eingabeseite für die Response ein Button angeboten, um die vollständige Tokenauswahl zu erhalten. Sollte nach der Filterung mit ''fudiscr.PreferredExcludeTokenPredicates'' eine Selektion durch die Nutzer*innen nicht mehr notwendig sein, wird sofort die Challenge erzeugt. Ergibt also z.B. die Filterung, dass nur //TOTP//-Token übrig bleiben und wurde ''fudiscr.user_token_selection=singleTokenTypeGroup'' konfiguriert, so wird sofort eine Challenge auf die //TOTP//-Token ausgelöst und die Eingabeseite für die Response angezeigt. Nutzer erhalten aber dann wie zuvor genannt die Möglichkeit, trotzdem andere Token-Verfahren auszuwählen. | |
| |
== Beispiel == | |
<file xml> | |
<util:list id="fudiscr.PreferredExcludeTokenPredicates"> | |
<bean class="de.zedat.fudis.shibboleth.idp.plugin.authn.fudiscr.function.impl.RegexExcludeTokenPropertiesPredicate" | |
c:propertyName="info:fudis_preferred" | |
c:excludePattern="^(?i)false$" | |
p:returnValueForNullInput="false"/> | |
<bean class="de.zedat.fudis.shibboleth.idp.plugin.authn.fudiscr.function.impl.RegexExcludeTokenPropertiesPredicate" | |
c:propertyName="type" | |
c:excludePattern="^totp$" | |
c:negateResult="true"/> | |
</util:list> | |
</file> | |
Das Beispiel filtert alle Token heraus, die nicht das Token-Info-Attribut ''fudis_preferred'' mit dem Wert ''true'' (case-insensitive) und nicht vom Typ 'totp' sind. ''p:returnValueForNullInput="false"'' bewirkt, dass das //RegexExcludeTokenPropertiesPredicate// bei fehlendem Token-(Info-)Attribut //false// zurückgibt. Bitte beachten Sie, dass durch ''c:negateResult="true"'' aus einem Exclude eine Include wird. In dem Beispiel werden im Gegensatz zu den vorherigen Filterbeispielen die Beans direkt in der Liste und nicht als Referenzen definiert. | |
| |
=== Realm-Transformation (ab Version 1.3.0) === | |
Es kann vorkommen, dass Nutzer im Identity Management über mehrere Datenquellen verteilt sind. So können z.B. Studierende und Beschätigte in zwei getrennten LDAP-Servern verwaltet werden. Dies führt wiederum dazu, dass z.B. in privacyIDEA zwei Realms angelegt werden müssen und bei den API-Anfragen gegen privacyIDEA müssen diese Realms unterschieden werden. Für das User-Objekt im fudiscr-Plugin wird folgende Logik durchlaufen, um den Realm zu ermitteln: | |
- Mit der Java-Klasse ''net.shibboleth.idp.session.context.navigate.CanonicalUsernameLookupStrategy'' wird zunächst gemäß Shibboleth-Standard der Benutzername aus den vorherigen Authentifizierungsergebnissen ermittelt. | |
- Anhand von ''fudiscr.username_realm_split_regex'' wird versucht, den Realm als gesondertes Attribut vom Benutzernamen abzutrennen. | |
- Wenn eine Liste ''fudiscr.UserRealmTransformationStrategies'' mit Realm-Transformationsstrategien in ''%{idp.home}/conf/authn/fudiscr.xml'' definiert wurde, dann werden diese Strategien in der aufgeführten Reihenfolge durchlaufen. | |
- Sollte noch kein Realm existieren, wird ein Default-Realm zugeordnet, wenn dieser mit ''fudiscr.default_users_realm'' definiert wurde. | |
Der so ermittelte Realm wird im fudiscr-Plugin von allen Klassen verwendet, die ein User-Objekt verarbeiten. | |
| |
Sollte der Realm im User-Objekt vom fudiscr-Plugin nicht definiert (//null//) sein, dann kann mit ''fudiscr.privacyidea.default_realm'' ein Realm für die API-Anfrage gegen privacyIDEA hinzugefügt werden. Der so hinzugefügte Realm wird aber **nicht** in das allgemeine User-Objekt vom fudiscr-Plugin übernommen! | |
| |
== Beispiel Realm-Transformationsstrategien == | |
<file xml> | |
<util:list id="fudiscr.UserRealmTransformationStrategies"> | |
<!-- The attribute specified under 'ldapAttributeName' must also be included in the list of 'idp.authn.LDAP.returnAttributes'. --> | |
<bean class="de.zedat.fudis.shibboleth.idp.plugin.authn.fudiscr.function.impl.UserRealmFromLdapPrincipalTransformationStrategy" | |
p:activeAuthenticationResultKey="authn/Password" | |
p:ldapAttributeName="realm"/> | |
| |
<!-- For ScriptedUserRealmTransformationStrategy: --> | |
<!-- Input1: profileRequestContext (org.opensaml.profile.context.ProfileRequestContext) --> | |
<!-- Input2: currentUserRealm (java.lang.String) --> | |
<!-- Output -> java.lang.String --> | |
<bean class="de.zedat.fudis.shibboleth.idp.plugin.authn.fudiscr.function.impl.ScriptedUserRealmTransformationStrategy" factory-method="inlineScript"> | |
<constructor-arg> | |
<value> | |
<![CDATA[ | |
newUserRealm = null; | |
| |
if (currentUserRealm == null) { | |
newUserRealm = "idp-users"; | |
} | |
| |
newUserRealm; | |
]]> | |
</value> | |
</constructor-arg> | |
</bean> | |
</util:list> | |
</file> | |
In dem Beispiel wird geprüft, ob in dem aktiven Authentifizierungsergebnis aus der Authentifizierung mit Benutzername und Passwort (//authn/Password//) ein //LdapPrincipal// existiert und ob dieser //LdapPrincipal// das Attribut //realm// enthält. Der erste Wert aus //realm// wird als Realm übernommen. Anschließend wird eine //Scripted// Strategie angewandt. | |
==== MFA-Konfiguration ==== | |
(Zum REFEDS Multi-Factor Authentication Profile siehe unter [[de:aai:refeds_authn_profiles_idp|REFEDS AuthN Profiles - Hinweise für Identity Provider]]) | (Zum REFEDS Multi-Factor Authentication Profile siehe unter [[de:aai:refeds_authn_profiles_idp|REFEDS AuthN Profiles - Hinweise für Identity Provider]]) |
\\ | \\ |
Hier können verschiedene Mechanismen verwendet werden, um die Bedingungen für die Übergänge in die nächsten Faktoren zu formulieren. | Hier können verschiedene Mechanismen verwendet werden, um die Bedingungen für die Übergänge in die nächsten Faktoren zu formulieren. |
Die offizielle Dokumentation dazu finden Sie hier: | Die offizielle Dokumentation dazu finden Sie hier: |
[[https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631610/MultiFactorAuthnConfiguration|MultiFactorAuthnConfiguration]] | [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199505534/MultiFactorAuthnConfiguration|MultiFactorAuthnConfiguration]] |
| |
=== Beispiele === | ==== Beispiele MFA-Konfiguration ==== |
| |
Im Folgenden werden drei Beispiele für eine MFA-Konfiguration aufgeführt | Im Folgenden werden drei Beispiele für eine MFA-Konfiguration aufgeführt. |
| |
**Beispiel 1**: Nach der Authentifizierung mit Benutzername und Passwort erfolgt immer eine tokenbasierte Authentifizierung mit fudiscr. | **Beispiel 1**: Nach der Authentifizierung mit Benutzername und Passwort erfolgt immer eine Token basierte Authentifizierung mit fudiscr. |
<file xml ./conf/authn/mfa-authn-config.xml> | <file xml ./conf/authn/mfa-authn-config.xml> |
<?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> |
default-destroy-method="destroy"> | default-destroy-method="destroy"> |
| |
<!-- most parts copied from https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631610/MultiFactorAuthnConfiguration --> | <!-- most parts copied from https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199505534/MultiFactorAuthnConfiguration --> |
| |
<util:map id="shibboleth.authn.MFA.TransitionMap"> | <util:map id="shibboleth.authn.MFA.TransitionMap"> |
</file> | </file> |
| |
**Beispiel 2**: Nach der Authentifizierung mit Benutzername und Passwort erfolgt dann eine tokenbasierte Authentifizierung, wenn die AuthenticationContextClass, die der ServiceProvider benötigt, nicht ausreicht. | **Beispiel 2**: Nach der Authentifizierung mit Benutzername und Passwort erfolgt dann eine Token basierte Authentifizierung, wenn die AuthenticationContextClass, die der ServiceProvider benötigt, nicht ausreicht. |
<file xml ./conf/authn/mfa-authn-config.xml> | <file xml ./conf/authn/mfa-authn-config.xml> |
<?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> |
default-destroy-method="destroy"> | default-destroy-method="destroy"> |
| |
<!-- most parts copied from https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631610/MultiFactorAuthnConfiguration --> | <!-- most parts copied from https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199505534/MultiFactorAuthnConfiguration --> |
| |
<util:map id="shibboleth.authn.MFA.TransitionMap"> | <util:map id="shibboleth.authn.MFA.TransitionMap"> |
</file> | </file> |
| |
**Beispiel 3**: Nach der Authentifizierung mit Benutzername und Passwort erfolgt dann eine tokenbasierte Authentifizierung, wenn die AuthenticationContextClass, die der ServiceProvider benötigt, nicht ausreicht oder wenn der/die Benutzer*in nach eduPersonAffiliation zu der Gruppe der Beschäftigten (employee) gehört. | **Beispiel 3**: Nach der Authentifizierung mit Benutzername und Passwort erfolgt dann eine Token basierte Authentifizierung, wenn die AuthenticationContextClass, die der ServiceProvider benötigt, nicht ausreicht oder wenn der/die Benutzer*in nach eduPersonAffiliation zu der Gruppe der Beschäftigten (employee) gehört. |
<file xml ./conf/authn/mfa-authn-config.xml> | <file xml ./conf/authn/mfa-authn-config.xml> |
<?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> |
default-destroy-method="destroy"> | default-destroy-method="destroy"> |
| |
<!-- most parts copied from https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631610/MultiFactorAuthnConfiguration --> | <!-- most parts copied from https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199505534/MultiFactorAuthnConfiguration --> |
| |
<util:map id="shibboleth.authn.MFA.TransitionMap"> | <util:map id="shibboleth.authn.MFA.TransitionMap"> |
| |
**Beispiel 4**: | **Beispiel 4**: |
<alert type="warning">Nachfolgendes Beispiel funktioniert erst ab der fudiscr-Version 1.1.0. Für Versionen 1.1.0 bis <1.3.0 kann //fudiscr.UserHasAnyTokenPredicate// anstelle von //fudiscr.UserHasTokenPredicate// verwendet werden.</alert> | Nach der Authentifizierung mit Benutzername und Passwort erfolgt dann eine Token basierte Authentifizierung, wenn die AuthenticationContextClass, die der ServiceProvider benötigt, nicht ausreicht oder wenn der/die Benutzer*in bereits mindestens einen Token besitzt. Bei den Tokens wird der Zustand nicht geprüft. Ein gesperrter Token würde z.B. dafür sorgen, dass das ''fudiscr.UserHasTokenPredicate'' den Wert ''true'' zurückgibt. Dieses Predicate wurde insbesondere für Rollout-Szenarien eingeführt. |
Nach der Authentifizierung mit Benutzername und Passwort erfolgt dann eine tokenbasierte Authentifizierung, wenn die AuthenticationContextClass, die der ServiceProvider benötigt, nicht ausreicht oder wenn der/die Benutzer*in bereits mindestens einen Token besitzt. Bei den Tokens wird der Zustand nicht geprüft. Ein gesperrter Token würde z.B. dafür sorgen, dass das ''fudiscr.UserHasTokenPredicate'' den Wert ''true'' zurückgibt. Dieses Predicate wurde insbesondere für Rollout-Szenarien eingeführt. | |
<file xml ./conf/authn/mfa-authn-config.xml> | <file xml ./conf/authn/mfa-authn-config.xml> |
<?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> |
| |
Für die Multi-Faktor-Authentifizierung gelten besondere Regeln. Eine Beschreibung finden Sie in der offiziellen Dokumentation unter | Für die Multi-Faktor-Authentifizierung gelten besondere Regeln. Eine Beschreibung finden Sie in der offiziellen Dokumentation unter |
[[https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631610/MultiFactorAuthnConfiguration|MultiFactorAuthnConfiguration]]. | [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199505534/MultiFactorAuthnConfiguration|MultiFactorAuthnConfiguration]]. |
| |
Mit folgender Konfiguration in ''%{idp.home}/conf/authn/authn.properties'' erreichen Sie, dass innerhalb einer Single-Sign-On-Session nur einmal Benutzername und Passwort verlangt wird, aber pro Service Provider Authentifizierung immer eine tokenbasierte Authentifizierung mit fudiscr. | Mit folgender Konfiguration in ''%{idp.home}/conf/authn/authn.properties'' erreichen Sie, dass innerhalb einer Single-Sign-On-Session nur einmal Benutzername und Passwort verlangt wird, aber pro Service Provider Authentifizierung immer eine Token basierte Authentifizierung mit fudiscr. |
<file properties ./conf/authn/authn.properties> | <file properties ./conf/authn/authn.properties> |
idp.authn.MFA.reuseCondition=shibboleth.Conditions.FALSE | idp.authn.MFA.reuseCondition=shibboleth.Conditions.FALSE |
</alert> | </alert> |
Wenn 'ForceAuthn' via SAML angefragt wird, dann gibt die Funktion ''mfaCtx.isAcceptable()'' immer ''false'' zurück. | Wenn 'ForceAuthn' via SAML angefragt wird, dann gibt die Funktion ''mfaCtx.isAcceptable()'' immer ''false'' zurück. |
==== Logging ==== | \\ |
| ===== AuthenticationFlowDescriptor für fudiscr ===== |
| Jedes Authentifizierungsverfahren im Shibboleth Identity Provider basiert auf einem abstrakten Flow mit einem AuthenticationFlowDescriptor, siehe hierzu [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199505085/AuthenticationConfiguration|AuthenticationConfiguration]]. |
| |
| Die Eigenschaften des AuthenticationFlowDescriptor werden in der Regel für alle Flows in ''%{idp.home}/conf/authn/authn.properties'' festgelegt. Als Vorlage sind diese auskommentiert in ''%{idp.home}/conf/authn/fudiscr.properties'' enthalten, um sie nach der Plugin-Installation bereitzustellen: |
| <file properties> |
| #idp.authn.fudiscr.order=1000 |
| #idp.authn.fudiscr.nonBrowserSupported=true |
| #idp.authn.fudiscr.passiveAuthenticationSupported=true |
| #idp.authn.fudiscr.forcedAuthenticationSupported=true |
| #idp.authn.fudiscr.proxyRestrictionsEnforced=%{idp.authn.fudiscr.forcedAuthenticationSupported:true} |
| #idp.authn.fudiscr.proxyScopingEnforced=false |
| #idp.authn.fudiscr.discoveryRequired=false |
| #idp.authn.fudiscr.lifetime=%{idp.authn.defaultLifetime:PT1H} |
| #idp.authn.fudiscr.inactivityTimeout=%{idp.authn.defaultTimeout:PT30M} |
| #idp.authn.fudiscr.reuseCondition=shibboleth.Conditions.TRUE |
| #idp.authn.fudiscr.activationCondition=shibboleth.Conditions.TRUE |
| #idp.authn.fudiscr.subjectDecorator= |
| #idp.authn.fudiscr.errorMessageFunction = DefaultPasswordErrorFunction |
| #idp.authn.fudiscr.genericMessageID = authn |
| #idp.authn.fudiscr.addDefaultPrincipals=true |
| #idp.authn.fudiscr.trimUsernamePrincipal=true |
| #idp.authn.fudiscr.lowercaseUsernamePrincipal=false |
| #idp.authn.fudiscr.uppercaseUsernamePrincipal=false |
| #idp.authn.fudiscr.supportedPrincipals= \ |
| # saml2/urn:de:zedat:fudis:SAML:2.0:ac:classes:CR |
| </file> |
| ''idp.authn.fudiscr.supportedPrincipals'' wurde bereits in der https://doku.tid.dfn.de/de:shibidp:plugin-fudiscr#mfa-konfiguration vorgestellt. |
| \\ |
| |
| ===== fudiscr-Konfiguration ===== |
| |
| ==== Hinweis zu älteren IdP-Konfigurationen ==== |
| Wenn Sie eine IdP-Konfiguration von vor Version 4.1.0 weiter pflegen, achten Sie bitte darauf, dass die Datei ''%{idp.home}/conf/idp.properties'' zu Beginn die folgende Zeile enthält, damit automatisch alle ''.properties''-Dateien unterhalb des ''%{idp.home}/conf''-Ordners (wie z.B. ''%{idp.home}/conf/fudiscr.properties'') eingelesen werden. |
| <file properties> |
| idp.searchForProperties=true |
| </file> |
| |
| ==== Konfigurationsdateien ==== |
| Mit der Installation des fudiscr-Plugins wird die Konfigurationsdatei ''%{idp.home}/conf/authn/fudiscr.properties'' abgelegt. Änderungen in dieser Datei werden in der Regel erst mit einem Neustart des Identity Providers wirksam. |
| |
| Außerdem wird die Konfigurationsdatei ''%{idp.home}/conf/authn/fudiscr.xml'' abgelegt. Die in dieser Datei enthaltenen Konfigurations-Beans werden über den [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199507931/ReloadableServices|ReloadableService]]-Mechanismus vom Shibboleth Identity Provider verwaltet (siehe auch [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199507931/ReloadableServices|ReloadableServices]]). |
| |
| Der Service kann wie folgt neu geladen werden: |
| <code> |
| %{idp.home}/bin/reload-service.sh -id fudiscr.ConfigurationBeansService |
| </code> |
| |
| Alternativ kann der Reload durch direkten Aufruf der URL ausgelöst werden und vermeidet Fehler durch den Wrapper in ''reload-service.sh''. |
| <code> |
| GET http(s)://[idp-base-url]/idp/profile/admin/reload-service?id=fudiscr.ConfigurationBeansService |
| </code> |
| |
| Analog zu den Parametern für die anderen [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199507931/ReloadableServices|ReloadableServices]] vom Shibboleth Identity Provider existieren für das fudiscr-Plugin die nachfolgenden: |
| <file properties> |
| fudiscr.service.failFast=false |
| fudiscr.service.checkInterval=PT0S |
| fudiscr.service.resources=fudiscr.ConfigurationResources |
| </file> |
| |
| Sollen Konfigurationsänderungen in ''%{idp.home}/conf/authn/fudiscr.xml'' automatisch geladen werden, so ist das Prüfintervall mit ''fudiscr.service.checkInterval'' zu setzen. Per Default (PT0S) ist die regelmäßige Prüfung der Veränderung des Zeitstempels von ''%{idp.home}/conf/authn/fudiscr.xml'' deaktiviert. |
| |
| ==== Allgemeine Konfigurationsoptionen ==== |
| Folgende allgemeine Konfigurationsoptionen können über die Konfigurationsdatei ''%{idp.home}/conf/authn/fudiscr.properties'' gesetzt werden. |
| ^Option^Default-Wert^Beschreibung^ |
| |**''fudiscr.challengeResponseClient''**|''EduMfaChallengeResponseClient''|Diese Option legt fest, welches Token-Backend angesprochen werden soll. Seit Version 2.1.0 ist der Default-Wert ''EduMfaChallengeResponseClient'', zuvor ''PrivacyIdeaChallengeResponseClient''. Es gibt auch die Möglichkeit, einen ''PrivacyIdeaChallengeResponseClient'' zu verwenden, der ohne Backend funktioniert und sämtliche Informationen als DEBUG-Meldungen beim Starten des IdP in die Logfiles schreibt.| |
| |''fudiscr.default_users_realm''|//leer//|Sollte sich kein Realm aus dem Benutzernamen ergeben, so kann mit dieser Option ein Realm festgelegt werden, der bei Fehlen im fudiscr-Plugin ergänzt wird. In den meisten Fällen wird kein Realm benötigt, so dass per Default kein Realm ergänzt wird. |
| |''fudiscr.filter_tokens.id_exclude_regex''|//leer//|Mit dieser Option können Token anhand ihrer ID/Seriennummer für die Verwendung im fudiscr-Plugin ausgeschlossen werden. Z.B. werden mit //^HOTP.*$// alle HOTP-Token ignoriert, die als Softwaretoken in privacyIDEA angelegt wurden und eine Seriennummer beginnend mit HOTP erhalten. Per Default wird der Filter nicht verwendet. Die Regular Expression ist nicht definiert.| |
| |''fudiscr.filter_tokens.type_exclude_regex''|//leer//|Mit dieser Option können Token-Typen für die Verwendung im fudiscr-Plugin ausgeschlossen werden. Z.B. werden mit //^totp$// alle TOTP-Token ignoriert. Per Default wird der Filter nicht verwendet. Die Regular Expression ist nicht definiert.| |
| |''fudiscr.on_failed_restart_completely_mfa''|''shibboleth.Conditions.FALSE''|Dieses [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199508946/PredefinedBeans|Predicate]] legt fest, ob bei einem Neustart der Authentifizieurung aus dem fudiscr-Plugin heraus nur der Faktor //fudiscr// im MFA-Flow (Default) oder die gesamte Authentifizierung neu gestartet wird. Gibt das [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199508946/PredefinedBeans|Predicate]] ''TRUE'' zurück, werden also die Ergebnisse der vorherigen Faktoren zurückgesetzt. Es werden also Benutzername und Passwort u.a. erneut verlangt.| |
| |''fudiscr.max_retries''|''10''|Anzahl an Fehlversuchen für die Validierung. Ist der Wert erreicht, wird die Validierung erfolglos beendet. Dieser Wert ist unabhängig von den erlaubten Fehlversuchen in privacyIDEA. Sollen ausschließlich die Fehlerzähler aus privacyIDEA wirken, so empfiehlt es sich, den Wert für ''fudiscr.max_retries'' passend zu erhöhen (> max. Failcounter in privacyIDEA).| |
| |''fudiscr.restart_allowed.max_retries_exceeded''|''shibboleth.Conditions.TRUE''|Dieses [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199508946/PredefinedBeans|Predicate]] legt fest, ob ein Neustart der Authentifizierung im fudiscr-Plugin erlaubt ist, wenn ''fudiscr.max_retries'' erreicht ist.| |
| |''fudiscr.restart_allowed.selected_tokens_not_available''|''shibboleth.Conditions.TRUE''|Dieses [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199508946/PredefinedBeans|Predicate]] legt fest, ob ein Neustart der Authentifizierung im fudiscr-Plugin erlaubt ist, wenn die durch Nutzer ausgewählten Token nicht mehr verfügbar sind (z.B. durch Sperrung in privacyIDEA).| |
| |''fudiscr.restart_allowed.within_response_page''|''shibboleth.Conditions.TRUE''|Dieses [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199508946/PredefinedBeans|Predicate]] legt fest, ob ein Neustart der fudiscr-Authentifizierung über die Eingabeseite für die Response (OTP, TAN u.a.) erlaubt ist.|| |
| |''fudiscr.result_idp_attribute_principal_attribute_name''|//leer//|Wird mit dieser Option ein Attributname angeben, so wird ein [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199503198/PrincipalNameAttributeDefinition|IdpAttributePrincipal]] mit diesem Attributnamen dem erfolgreichen Authentifizierungsergebnis des fudiscr-Plugins hinzugefügt. Der Attributwert enthält die ID/Seriennummer des Token, mit dem die Authentifizierung erfolgt ist.| |
| |''fudiscr.result_idp_attribute_principal_attribute_name_for_token_type''|//leer//|Wird mit dieser Option ein Attributname angeben, so wird ein [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199503198/PrincipalNameAttributeDefinition|IdpAttributePrincipal]] mit diesem Attributnamen dem erfolgreichen Authentifizierungsergebnis des fudiscr-Plugins hinzugefügt. Der Attributwert enthält den Token-Typ des Token, mit dem die Authentifizierung erfolgt ist.| |
| |''fudiscr.result_with_realm_in_username_principal''|''shibboleth.Conditions.FALSE''|Wenn mit ''fudiscr.result_with_username_principal'' ein [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199505212/AttributePostLoginC14NConfiguration|UsernamePrincipal]] erzeugt wird, dann legt dieses [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199508946/PredefinedBeans|Predicate]] fest, ob der Realm enthalten ist. ''TRUE'' (default) erzeugt z.B. //dummy@fu-berlin.de//, ''FALSE'' nur //dummy// als Username.| |
| |''fudiscr.result_with_username_principal''|''shibboleth.Conditions.TRUE''|Dieses [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199508946/PredefinedBeans|Predicate]] legt fest, ob nach erfolgreicher Authentifizierung ein [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199505212/AttributePostLoginC14NConfiguration|UsernamePrincipal]] dem Subject hinzugefügt wird. Per Default enthält das Authentifizierungsergebnis nach erfolgreicher Authentifizierung mit dem fudiscr-Plugin einen [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199505212/AttributePostLoginC14NConfiguration|UsernamePrincipal]].| |
| |''fudiscr.username_realm_split_regex''|''@''|Aus einem vorherigen Faktor wird bei der Authentifizierung ein Benutzername erzeugt. Dieser kann auch einen Realm enthalten, z.B. //dummy@fu-berlin.de//. Mit dieser Option wird das Trennzeichen festgelegt, anhand dessen die Auftrennung in Benutzernamen und Realm erfolgt. Der Defaultwert ist ''@''| |
| |''fudiscr.user_token_selection''|''none''|Diese Option legt fest, ob Token durch Nutzer*innen ausgewählt werden können. Mögliche Werte sind: ''none''=keine Auswahl, ''singleToken''=Auswahl eines einzelnen Token (anhand der ID/Seriennummer), ''multipleToken''=Auswahl mehrerer Token (anhand der Seriennummer), ''singleTokenTypeGroup''=Auswahl eines einzelnen Tokentyps (z.B. totp), ''singleTokenTypeGroup''=Auswahl mehrerer Token-Typen. Per Default (''none'') wird eine Challenge für alle aktive Token erzeugt.| |
| |
| |
| |
| ==== Konfigurationsoptionen für eduMFA/privacyIDEA ==== |
| === eduMFA === |
| siehe [[de:shibidp:plugin-fudiscr:edumfa_setup|Installation und Konfiguration von eduMFA]] |
| === privacyIDEA === |
| siehe [[de:shibidp:plugin-fudiscr:privacyidea_setup|Installation und Konfiguration von privacyIDEA]] |
| \\ |
| |
| |
| ==== Filterung von Token ==== |
| Token können anhand von Eigenschaften wie Token-ID/-Seriennummer, -Status, -Typ u.a. herausgefiltert werden. Außerdem können für die Filterung die Eigenschaften aus einer SAML- oder OIDC-Anfrage genutzt werden. Hierzu gehören z.B. die entityID des Service Provider, die Authentication Context Class oder die IP-Adresse der Nutzer*innen. |
| |
| === Generelle Filterung via Regular Expressions === |
| Allgemein können Token anhand ihres Typs oder ihrer ID/Seriennummer mit den (o.g.) Konfigurationsoptionen ''fudiscr.filter_tokens.type_exclude_regex'' und ''fudiscr.filter_tokens.id_exclude_regex'' in ''%{idp.home}/conf/authn/fudiscr.properties'' ausgeschlossen werden. |
| |
| <file properties> |
| fudiscr.filter_tokens.type_exclude_regex=^(sms|web_authn)$ |
| </file> |
| In diesem Beispiel werden alle SMS- und WebAuthn-Token herausgefiltert. |
| |
| <file properties> |
| fudiscr.filter_tokens.id_exclude_regex=^(OATH|TOTP).+$ |
| </file> |
| In diesem Beispiel werden alle Token herausgefiltert, die den Präfix OATH oder TOTP in der Seriennummer besitzen. Das betrifft in eduMFA und privacyIDEA alle HOTP- und TOTP-Token |
| |
| === Filterung mit erweiterten Ausschlussbedingungen === |
| In ''%{idp.home}/conf/authn/fudiscr.xml'' können erweiterte Ausschlussbedingungen definiert werden. Die Bedingungen werden in der Liste ''fudiscr.ExcludeTokenPredicates'' zusammengefasst und nacheinander abgearbeitet. |
| |
| <file xml> |
| <util:list id="fudiscr.ExcludeTokenPredicates"> |
| <ref bean="fudiscr.ExcludeTokenPredicate1"/> |
| <ref bean="fudiscr.ExcludeTokenPredicate2"/> |
| <ref bean="fudiscr.ExcludeTokenPredicate3"/> |
| <!-- usw. --> |
| </util:list> |
| </file> |
| In diesem Beispiel wird gezeigt, wie die Ausschlussliste generell definiert wird. |
| |
| Die Ausschlussbedingungen können //Scripted// oder anhand von //Regular Expressions// bezogen auf Token-Eigenschaften formuliert werden. |
| \\ |
| \\ |
| |
| == Beispiel Scripted == |
| <file xml> |
| <util:list id="fudiscr.ExcludeTokenPredicates"> |
| <ref bean="fudiscr.ScriptedExcludeTokenPredicateExample1"/> |
| </util:list> |
| |
| <!-- Input1: profileRequestContext (org.opensaml.profile.context.ProfileRequestContext) --> |
| <!-- Input2: token (de.zedat.fudis.shibboleth.idp.plugin.authn.fudiscr.domain.Token) --> |
| <!-- Output -> java.lang.Boolean / boolean --> |
| <bean id="fudiscr.ScriptedExcludeTokenPredicateExample1" parent="fudiscr.Functions.ScriptedExcludeTokenPredicate" factory-method="inlineScript"> |
| <constructor-arg> |
| <value> |
| <![CDATA[ |
| // default is to keep the token |
| exclude = false; |
| |
| relyingPartyId = profileContext.getSubcontext("net.shibboleth.profile.context.RelyingPartyContext").getRelyingPartyId(); |
| |
| // if the service provider is not 'https://portal.local/shibboleth', tokens that are of type 'registration_code' are excluded |
| if (!relyingPartyId.equals("https://portal.local/shibboleth") && token.getType().toString().equalsIgnoreCase("registration_code")) { |
| exclude = true; |
| } |
| |
| exclude; |
| ]]> |
| </value> |
| </constructor-arg> |
| </bean> |
| </file> |
| In diesem Beispiel dürfen Notfallcodes (//registration_code//) nur für ein (Service-)Portal und sonst keinen anderen Service Provider verwendet werden. Nutzer*innen können sich mit Hilfe der Notfallcodes wieder andere Token-Verfahren im (Service-)Portal einrichten bzw. freischalten. |
| \\ |
| \\ |
| |
| == Beispiel mit Regular Expression == |
| <file xml> |
| <util:list id="fudiscr.ExcludeTokenPredicates"> |
| <ref bean="fudiscr.RegexExcludeTokenPredicateExample1"/> |
| <ref bean="fudiscr.RegexExcludeTokenPredicateExample2"/> |
| </util:list> |
| |
| <bean id="fudiscr.RegexExcludeTokenPredicateExample1" |
| class="de.zedat.fudis.shibboleth.idp.plugin.authn.fudiscr.function.impl.RegexExcludeTokenPropertiesPredicate" |
| c:propertyName="rollout_state" |
| c:excludePattern="^verify$"/> |
| <bean id="fudiscr.RegexExcludeTokenPredicateExample2" |
| class="de.zedat.fudis.shibboleth.idp.plugin.authn.fudiscr.function.impl.RegexExcludeTokenPropertiesPredicate" |
| c:propertyName="rollout_state" |
| c:excludePattern="^clientwait$"/> |
| </file> |
| In diesem Beispiel werden Token anhand einer Token-Eigenschaft herausgefiltert. In eduMFA und privacyIDEA können aktive Token existieren, die eine erste Validierung erfordern, bevor sie effektiv verwendet werden können. So soll z.B. erzwungen werden, dass Nutzer*innen bei der Einrichtung eines TOTP-Token den QR-Code mit dem Authenticator einscannen und diesen Vorgang mit einem OTP bestätigen. Die Token besitzen bis zur Bestätigung die Eigenschaft //rollout_state// mit den Werten //verify// oder //clientwait//. Die in dem Beispiel verwendeten zwei Predicates lassen sich auch mit einem Predicate und der Regular Expression //^(clientwait|verify)$// abbilden. Es soll in dem Beispiel nur die Listeneigenschaft von ''fudiscr.ExcludeTokenPredicates'' verdeutlicht werden. |
| |
| (Mit dem Konstruktor-Parameter ''c:negateResult="true"'' kann das Ergbnis eines //ExcludeTokenPredicates// negiert werden.) |
| \\ |
| \\ |
| |
| |
| ==== Funktion fudiscr.UserHasTokenPredicate ==== |
| Mit der Bean ''fudiscr.UserHasTokenPredicate'' wird eine Funktion zur Verfügung gestellt, um zu entscheiden, ob Nutzer*innen generell schon für den zweiten Faktor bzw. für ein Token-Verfahren eingerichtet wurden. Diese Funktion kann insbesondere in der Rollout-Phase von Nutzen sein. Die Entscheidung, ob Nutzer*innen für einen zweiten Faktor aktiviert sind, kann aber auch über z.B. Gruppen in einem LDAP-Verzeichnisdienst gesteuert werden. |
| |
| Auch für diese Funktion werden die zuvor genannten Filtermöglichkeiten per Beans in ''%{idp.home}/conf/authn/fudiscr.xml'' angeboten. Die verwendete Filter-Liste hat die id ''fudiscr.UserHasTokenExcludeTokenPredicates''. Sollen die Filterlisten ''fudiscr.ExcludeTokenPredicates'' und ''fudiscr.UserHasTokenExcludeTokenPredicates''von identisch sein, so kann für ''fudiscr.UserHasTokenExcludeTokenPredicates'' ein Alias definiert werden: |
| |
| <file xml> |
| <alias name="fudiscr.ExcludeTokenPredicates" alias="fudiscr.UserHasTokenExcludeTokenPredicates"/> |
| </file> |
| \\ |
| |
| |
| ==== vorselektierte Token ==== |
| Äquivalent zu den Filtern ''fudiscr.ExcludeTokenPredicates'' und ''fudiscr.UserHasTokenExcludeTokenPredicates'' kann ein Filter definiert werden, der die bevorzugten Token eines Nutzers herausfiltert. Wird die Exclude-Filter-Liste ''fudiscr.PreferredExcludeTokenPredicates'' definiert, so werden initial nur die bevorzugten Token verwendet. Führt die Filterung dazu, dass alle Token ausgeschlossen werden, wird die Filterung zurückgesetzt. Sollte die Filterung die Ausgangsliste reduzieren, so wird dem Nutzer auf der Auswahlseite für die Token und der Eingabeseite für die Response ein Button angeboten, um die vollständige Token-Auswahl zu erhalten. Sollte nach der Filterung mit ''fudiscr.PreferredExcludeTokenPredicates'' eine Selektion durch die Nutzer*innen nicht mehr notwendig sein, wird sofort die Challenge erzeugt. Ergibt also z.B. die Filterung, dass nur //TOTP//-Token übrig bleiben und wurde ''fudiscr.user_token_selection=singleTokenTypeGroup'' konfiguriert, so wird sofort eine Challenge auf die //TOTP//-Token ausgelöst und die Eingabeseite für die Response angezeigt. Nutzer erhalten aber dann wie zuvor genannt die Möglichkeit, trotzdem andere Token-Verfahren auszuwählen. |
| |
| === Beispiel Preferred === |
| <file xml> |
| <util:list id="fudiscr.PreferredExcludeTokenPredicates"> |
| <bean class="de.zedat.fudis.shibboleth.idp.plugin.authn.fudiscr.function.impl.RegexExcludeTokenPropertiesPredicate" |
| c:propertyName="info:fudis_preferred" |
| c:excludePattern="^(?i)no$" |
| p:defaultValueForMissingProperty="no"/> |
| <bean class="de.zedat.fudis.shibboleth.idp.plugin.authn.fudiscr.function.impl.RegexExcludeTokenPropertiesPredicate" |
| c:propertyName="type" |
| c:excludePattern="^totp$" |
| c:negateResult="true"/> |
| </util:list> |
| </file> |
| Das Beispiel filtert alle Token heraus, die nicht das Token-Info-Attribut ''fudis_preferred'' mit dem Wert ''true'' (case-insensitive) und nicht vom Typ 'totp' sind. ''p:defaultValueForMissingProperty="no"'' bewirkt, dass das //RegexExcludeTokenPropertiesPredicate// bei fehlendem Token-(Info-)Attribut //no// zurückgibt. Bitte beachten Sie, dass durch ''c:negateResult="true"'' aus einem Exclude ein Include wird. In dem Beispiel werden im Gegensatz zu den vorherigen Filterbeispielen die Beans direkt in der Liste und nicht als Referenzen definiert. |
| \\ |
| \\ |
| |
| |
| ==== Realm-Transformation ==== |
| Es kann vorkommen, dass Nutzer*innen im Identity Management über mehrere Datenquellen verteilt sind. So können z.B. Studierende und Beschäftigte in zwei getrennten LDAP-Servern verwaltet werden. Dies führt wiederum dazu, dass z.B. in eduMFA oder privacyIDEA zwei Realms angelegt werden müssen und bei den API-Anfragen müssen diese Realms unterschieden werden. Für das User-Objekt im fudiscr-Plugin wird folgende Logik durchlaufen, um den Realm zu ermitteln: |
| - Mit der Java-Klasse ''net.shibboleth.idp.session.context.navigate.CanonicalUsernameLookupStrategy'' wird zunächst gemäß Shibboleth-Standard der Benutzername aus den vorherigen Authentifizierungsergebnissen ermittelt. |
| - Anhand von ''fudiscr.username_realm_split_regex'' wird versucht, den Realm als gesondertes Attribut vom Benutzernamen abzutrennen. |
| - Wenn eine Liste ''fudiscr.UserRealmTransformationStrategies'' mit Realm-Transformationsstrategien in ''%{idp.home}/conf/authn/fudiscr.xml'' definiert wurde, dann werden diese Strategien in der aufgeführten Reihenfolge durchlaufen. |
| - Sollte noch kein Realm existieren, wird ein Default-Realm zugeordnet, wenn dieser mit ''fudiscr.default_users_realm'' definiert wurde. |
| Der so ermittelte Realm wird im fudiscr-Plugin von allen Klassen verwendet, die ein User-Objekt verarbeiten. |
| |
| Sollte der Realm im User-Objekt vom fudiscr-Plugin nicht definiert (//null//) sein, dann kann mit ''fudiscr.edumfa.default_realm'' ein Realm für die API-Anfrage gegen eduMFA bzw. mit ''fudiscr.privacyidea.default_realm'' gegen privacyIDEA hinzugefügt werden. Der so hinzugefügte Realm wird aber **nicht** in das allgemeine User-Objekt vom fudiscr-Plugin übernommen! |
| |
| === Beispiel UserRealmTransformationStrategies === |
| <file xml> |
| <util:list id="fudiscr.UserRealmTransformationStrategies"> |
| <!-- The attribute specified under 'ldapAttributeName' must also be included in the list of 'idp.authn.LDAP.returnAttributes'. --> |
| <bean class="de.zedat.fudis.shibboleth.idp.plugin.authn.fudiscr.function.impl.UserRealmFromLdapPrincipalTransformationStrategy" |
| p:activeAuthenticationResultKey="authn/Password" |
| p:ldapAttributeName="realm"/> |
| |
| <!-- For ScriptedUserRealmTransformationStrategy: --> |
| <!-- Input1: profileRequestContext (org.opensaml.profile.context.ProfileRequestContext) --> |
| <!-- Input2: currentUserRealm (java.lang.String) --> |
| <!-- Output -> java.lang.String --> |
| <bean class="de.zedat.fudis.shibboleth.idp.plugin.authn.fudiscr.function.impl.ScriptedUserRealmTransformationStrategy" factory-method="inlineScript"> |
| <constructor-arg> |
| <value> |
| <![CDATA[ |
| newUserRealm = null; |
| |
| if (currentUserRealm == null) { |
| newUserRealm = "idp-users"; |
| } |
| |
| newUserRealm; |
| ]]> |
| </value> |
| </constructor-arg> |
| </bean> |
| </util:list> |
| </file> |
| In dem Beispiel wird geprüft, ob in dem aktiven Authentifizierungsergebnis aus der Authentifizierung mit Benutzername und Passwort (//authn/Password//) ein //LdapPrincipal// existiert und ob dieser //LdapPrincipal// das Attribut //realm// enthält. Der erste Wert aus //realm// wird als Realm übernommen. Anschließend wird eine //Scripted// Strategie angewandt. |
| \\ |
| \\ |
| |
| ==== Subject Customizers ==== |
| Das [[https://refeds.org/assurance|REFEDS Assurance Framework]] definiert u.a. Profile für die Multifaktor-Authentifizierung. Grundsätzlich können Service Provider per Authentication Context Class Eigenschaften verlangen, die nur auf bestimmte Token zutreffen. Eine Filterung der passenden Token ist mit ''fudiscr.ExcludeTokenPredicates'' im möglich, aber bei der Frage, ob ein Authentifizierungsergebnis in einer SSO-Session für einen anderen Service Provider genutzt werden kann, nützt diese Filterung nichts. |
| |
| Authentication Context Classes werden im Shibboleth Identity Provider als Principals abgebildet. Jedes Authentifizierungsverfahren besitzt die Eigenschaften ''idp.authn.<flowid>.supportedPrincipals'' und ''idp.authn.<flowid>.addDefaultPrincipals'' (Default: true). Die ''idp.authn.<flowid>.supportedPrincipals'' entscheiden darüber, ob das jeweilige Authentifizierungsverfahren zu der angefragten Authentication Context Class passt. Mit ''idp.authn.<flowid>.addDefaultPrincipals=true'' werden die ''idp.authn.<flowid>.supportedPrincipals'' zum Authentifizierungsergebnis hinzugefügt. |
| |
| Die Listen-Bean ''fudiscr.SubjectCustomizers'' ermöglicht es, die Principals für die Authentication Context Class zu modifizieren. |
| |
| Zusätzlich werden zwei Funktionen als Reuse-Conditions angeboten. |
| |
| ''fudiscr.FlowSpecificRequestedPrincipalsReuseCondition'' verlangt nochmal den einzelnen (zweiten) Faktor, wenn die bisherigen Authentication Context Classes nicht ausreichen. ''fudiscr.GeneralRequestedPrincipalsReuseCondition verlangt'' alle Faktoren, wenn die bisherigen Authentication Context Classes nicht ausreichen. |
| |
| Das nachfolgende Beispiel zeigt das Zusammenspiel der Konfigurationselemente. |
| |
| === Beispiel SubjectCustomizers mit supportedPrincipals und ReuseConditions === |
| In ''%{idp.home}/conf/authn/authn.properties'' werden für das Authentifizierungsverfahren ''fudiscr'' die ''supportedPrincipals'' definiert: |
| <file properties> |
| idp.authn.fudiscr.supportedPrincipals= \ |
| saml2/urn:de:zedat:fudis:SAML:2.0:ac:classes:CR, \ |
| saml2/urn:de:zedat:fudis:SAML:2.0:ac:classes:CR:IAP:LOW, \ |
| saml2/urn:de:zedat:fudis:SAML:2.0:ac:classes:CR:IAP:HIGH |
| </file> |
| |
| Für den MFA-Flow müssen alle supportedPrincipals definiert werden, die durch die einzelnen verwendeten Faktoren in Summe abgedeckt werden. Besteht der erste Faktor aus dem üblichen Abfrage nach Benutzernamen und Password (flowid=password), dann sollte der Eintrag in der ''%{idp.home}/conf/authn/authn.properties'' wie folgt aussehen: |
| |
| <file properties> |
| idp.authn.MFA.supportedPrincipals = \ |
| saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:InternetProtocol, \ |
| saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport, \ |
| saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:Password, \ |
| saml1/urn:oasis:names:tc:SAML:1.0:am:password, \ |
| saml2/urn:de:zedat:fudis:SAML:2.0:ac:classes:CR, \ |
| saml2/urn:de:zedat:fudis:SAML:2.0:ac:classes:CR:IAP:LOW, \ |
| saml2/urn:de:zedat:fudis:SAML:2.0:ac:classes:CR:IAP:HIGH |
| </file> |
| |
| In der ''%{idp.home}/conf/authn/fudiscr.xml'' wird nun ein Subject Customizer definiert, der für ''fudiscr'' immer die Authentication Context Class ''saml2/urn:de:zedat:fudis:SAML:2.0:ac:classes:CR'' hinzufügt. Abhängig von den Eigenschaften des erfolgreich verwendeten Tokens wird entweder nur ''saml2/urn:de:zedat:fudis:SAML:2.0:ac:classes:CR:IAP:LOW'' oder ''saml2/urn:de:zedat:fudis:SAML:2.0:ac:classes:CR:IAP:LOW'' sowie ''saml2/urn:de:zedat:fudis:SAML:2.0:ac:classes:CR:IAP:HIGH'' ergänzt. |
| |
| <file xml> |
| <util:list id="fudiscr.SubjectCustomizers"> |
| <ref bean="fudiscr.ScriptedAuthenticationMethodAndContextPrincipalsTokenBasedSubjectCustomizer"/> |
| </util:list> |
| |
| <bean id="fudiscr.ScriptedAuthenticationMethodAndContextPrincipalsTokenBasedSubjectCustomizer" parent="fudiscr.Functions.ScriptedAuthenticationMethodAndContextPrincipalsSubjectCustomizer" factory-method="inlineScript"> |
| <constructor-arg> |
| <value> |
| <![CDATA[ |
| var logger = Java.type( "org.slf4j.LoggerFactory" ).getLogger("fudiscr.ScriptedAuthenticationMethodAndContextPrincipalsSubjectCustomizer"); |
| logger.trace("Input 1, principals: '{}'", principals); |
| logger.trace("Input 2, token: '{}'", token) |
| var HashSet = Java.type("java.util.HashSet"); |
| var newPrincipals = new HashSet(); |
| |
| var AuthnContextClassRefPrincipal = Java.type("net.shibboleth.idp.saml.authn.principal.AuthnContextClassRefPrincipal"); |
| var standardPrincipal = new AuthnContextClassRefPrincipal("urn:de:zedat:fudis:SAML:2.0:ac:classes:CR"); |
| newPrincipals.add(standardPrincipal); |
| if (token.getProperties().get("description") != null && token.getProperties().get("description").toString().equalsIgnoreCase("IAP=high")) { |
| var lowPrincipal = new AuthnContextClassRefPrincipal("urn:de:zedat:fudis:SAML:2.0:ac:classes:CR:IAP:LOW"); |
| newPrincipals.add(lowPrincipal); |
| var highPrincipal = new AuthnContextClassRefPrincipal("urn:de:zedat:fudis:SAML:2.0:ac:classes:CR:IAP:HIGH"); |
| newPrincipals.add(highPrincipal); |
| } |
| |
| if (token.getProperties().get("description") != null && token.getProperties().get("description").toString().equalsIgnoreCase("IAP=low")) { |
| var lowPrincipal = new AuthnContextClassRefPrincipal("urn:de:zedat:fudis:SAML:2.0:ac:classes:CR:IAP:LOW"); |
| newPrincipals.add(lowPrincipal); |
| } |
| |
| logger.trace("Result, newPrincipals: '{}'", newPrincipals); |
| newPrincipals; |
| ]]> |
| </value> |
| </constructor-arg> |
| </bean> |
| </file> |
| |
| In ''%{idp.home}/conf/authn/authn.properties'' können nun die zwei Varianten für die Reuse Conditions gesetzt werden. |
| |
| Variante 1: Nur der zweite Faktor wird noch einmal verlangt, wenn die bisherigen Authentication Context Classes nicht ausreichen. |
| <file properties> |
| idp.authn.MFA.reuseCondition=shibboleth.Conditions.FALSE |
| idp.authn.Password.reuseCondition=shibboleth.Conditions.TRUE |
| idp.authn.fudiscr.reuseCondition=fudiscr.FlowSpecificRequestedPrincipalsReuseCondition |
| </file> |
| |
| Variante 2: Alle Faktoren werden wieder verlangt, wenn die bisherigen Authentication Context Classes nicht ausreichen. |
| <file properties> |
| idp.authn.MFA.reuseCondition=shibboleth.Conditions.FALSE |
| idp.authn.Password.reuseCondition=fudiscr.GeneralRequestedPrincipalsReuseCondition |
| idp.authn.fudiscr.reuseCondition=fudiscr.GeneralRequestedPrincipalsReuseCondition |
| </file> |
| \\ |
| |
| ==== Subject Canonicalization ==== |
| Als Zusatzangebot kann für den Prozess der [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199512211/SubjectCanonicalization|SubjectCanonicalization]] im Shibboleth Identity Provider ein Flow auf Basis von ''de.zedat.fudis.shibboleth.idp.plugin.authn.fudiscr.domain.ChallengeResponseTokenIdPrincipal'' aktiviert werden. Dieser vom fudiscr-Plugin erzeugte zusätzliche Principal enthält die ID/Seriennummer des erfolgreich verwendeten Token. |
| |
| Um den Flow zu aktivieren, muss in der Konfigurationsdatei ''%{idp.home}/conf/c14n/subject-c14n.xml'' die Referenz ''<ref bean="c14n/fudiscr" />'' in die Liste ''shibboleth.PostLoginSubjectCanonicalizationFlows'' aufgenommen werden. |
| |
| Zusätzlich können wie für andere Principals Transformationsoptionen z.B.in ''%{idp.home}/conf/c14n/subject-c14n.properties'' angegeben werden: |
| <file properties> |
| idp.c14n.fudiscr.lowercase=false |
| idp.c14n.fudiscr.uppercase=false |
| idp.c14n.fudiscr.trim=true |
| </file> |
| \\ |
| |
| ===== fudispasskeys-Konfiguration (nur eduMFA) ===== |
| Mit fudispasskeys wird ein Authentifizierungsverfahren angeboten, das sich in die Login-Seite für die Authentifizierung mit Benutzernamen und Passwort integrieren lässt und eine direkte Authentifizierung mit einem Sicherheitsschlüssel bzw. Passkeys ermöglicht. Die Konfiguration erfolgt in folgenden Schritten: |
| \\ |
| === Verwendung des EduMfaChallengeResponseClient === |
| Das Verfahren wird nur vom ''EduMfaChallengeResponseClient'' in Zusammenspiel mit eduMFA unterstützt. In ''%{idp.home}/conf/authn/fudiscr.properties'' muss also die folgende Eigenschaft gesetzt sein: |
| <file properties> |
| fudiscr.challengeResponseClient=EduMfaChallengeResponseClient |
| </file> |
| |
| === Definition der Relying Party Id für WebAuthn/Passkeys === |
| Zusätzlich muss in ''%{idp.home}/conf/authn/fudiscr.properties'' die Relying Party Id für WebAuthn/Passkeys gemäß der enrollment policy [[https://edumfa.readthedocs.io/en/v2.2.0/policies/enrollment.html#policy-webauthn-enroll-relying-party-id|webauthn_relying_party_id]] aus eduMFA gesetzt werden: |
| <file properties> |
| fudispasskeys.relying_party_id=<same value here as in the enrollment policy 'webauthn_relying_party_id' in eduMFA> |
| </file> |
| |
| === Definition/Erweiterung der Bean shibboleth.CustomViewContext === |
| Um in den Views auf spezielle Funktionen zugreifen zu können, muss in der ''%{idp.home}/conf/global.xml'' die Bean ''shibboleth.CustomViewContext'' definiert oder erweitert werden. Es handelt sich hierbei um eine Liste, die mindestens einen Eintrag für die ''fudispasskeys.ChallengeGenerationStrategy'' benötigt: |
| <file xml> |
| <util:map id="shibboleth.CustomViewContext"> |
| <!-- hier die bisherigen Einträge --> |
| <entry key="fudispasskeys.ChallengeGenerationStrategy" value-ref="fudispasskeys.ChallengeGenerationStrategy" /> |
| </util:map> |
| </file> |
| |
| === Anpassung von authn-events-flow.xml === |
| In der ''%{idp.home}/conf/authn/authn-events-flow.xml'' müssen folgende Erweiterungen vorgenommen werden: |
| |
| <file xml> |
| <flow xmlns="http://www.springframework.org/schema/webflow" |
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow.xsd" |
| abstract="true"> |
| |
| <!-- Custom error events to reflect back from user-supplied login subflows. --> |
| <!-- <end-state id="MyCustomEvent" /> --> |
| <end-state id="fudispasskeys" /><!-- add this for fudispasskeys --> |
| |
| <global-transitions> |
| <!-- <transition on="MyCustomEvent" to="MyCustomEvent" /> --> |
| <transition on="fudispasskeys" to="fudispasskeys" /><!-- add this for fudispasskeys --> |
| <transition on="#{!'proceed'.equals(currentEvent.id)}" to="InvalidEvent" /> |
| </global-transitions> |
| |
| </flow> |
| </file> |
| |
| === Anpassung von mfa-authn-config.xml === |
| In der bestehenden ''%{idp.home}/conf/authn/mfa-authn-config.xml'' muss die ''shibboleth.authn.MFA.TransitionMap'' erweitert werden: |
| |
| <file xml> |
| <util:map id="shibboleth.authn.MFA.TransitionMap"> |
| <entry key=""> |
| <bean parent="shibboleth.authn.MFA.Transition" p:nextFlow="authn/fudispasskeys"/> |
| </entry> |
| <entry key="authn/fudispasskeys"> |
| <bean parent="shibboleth.authn.MFA.Transition"> |
| <property name="nextFlowStrategyMap"> |
| <map> |
| <entry key="NoCredentials" value="authn/Password" /> |
| <entry key="InvalidCredentials" value="authn/Password" /> |
| </map> |
| </property> |
| </bean> |
| </entry> |
| <entry key="authn/Password"> |
| <bean parent="shibboleth.authn.MFA.Transition"> |
| <property name="nextFlowStrategyMap"> |
| <map> |
| <entry key="fudispasskeys" value="authn/fudispasskeys" /><!-- add this for fudispasskeys --> |
| <entry key="proceed" value-ref="checkSecondFactor" /><!-- or the previous entry for the second factor --> |
| </map> |
| </property> |
| </bean> |
| </entry> |
| </util:map> |
| </file> |
| |
| === Anpassung von login.vm === |
| In der ''%{idp.home}/views/login.vm'' muss außerhalb des Login-Formulars folgende Zeile eingefügt werden: |
| <file xml> |
| #parse("fudispasskeys/login-passkeys.vm") |
| </file> |
| |
| Zusätzlich kann bei den Input-Feldern für Benutzernamen und Passwort das Attribut ''autocomplete'' mit dem Wert ''webauthn'' eingefügt bzw. ergänzt werden, z.B. |
| <file xml> |
| autocomplete="webauthn" |
| </file> |
| |
| Dadurch wird zusätzlich eine Passkeys-Authentifizierung angeboten, wenn man diese Input-Felder auswählt. |
| |
| === Policies in eduMFA === |
| Gemäß [[https://doku.tid.dfn.de/de:shibidp:plugin-fudiscr:edumfa_setup#richtlinien_fuer_fudispasskeys|eduMFA-Richtlinien für fudispasskeys]] müssen folgende authentication- und enrollment-Policies in eduMFA gesetzt sein: |
| |
| für den Scope authentication: |
| <file properties> |
| webauthn_user_verification_requirement = required |
| webauthn_usernameless_authn = True |
| </file> |
| |
| für den Scope enrollment: |
| <file properties> |
| webauthn_relying_party_id = <domain of your institution> |
| webauthn_relying_party_name = <name of the relying party> |
| webauthn_resident_key = required |
| webauthn_user_verification_requirement = required |
| </file> |
| |
| ==== AuthenticationFlowDescriptor für fudispasskeys ==== |
| Analog zum [[https://doku.tid.dfn.de/de:shibidp:plugin-fudiscr#authenticationflowdescriptor_fuer_fudiscr|AuthenticationFlowDescriptor für fudiscr]] existiert auch ein AuthenticationFlowDescriptor für fudispasskeys: |
| |
| <file properties> |
| #idp.authn.fudispasskeys.order=1000 |
| #idp.authn.fudispasskeys.nonBrowserSupported=true |
| #idp.authn.fudispasskeys.passiveAuthenticationSupported=true |
| #idp.authn.fudispasskeys.forcedAuthenticationSupported=true |
| #idp.authn.fudispasskeys.proxyRestrictionsEnforced=%{idp.authn.fudispasskeys.forcedAuthenticationSupported:true} |
| #idp.authn.fudispasskeys.proxyScopingEnforced=false |
| #idp.authn.fudispasskeys.discoveryRequired=false |
| #idp.authn.fudispasskeys.lifetime=%{idp.authn.defaultLifetime:PT1H} |
| #idp.authn.fudispasskeys.inactivityTimeout=%{idp.authn.defaultTimeout:PT30M} |
| #idp.authn.fudispasskeys.reuseCondition=shibboleth.Conditions.TRUE |
| #idp.authn.fudispasskeys.activationCondition=shibboleth.Conditions.TRUE |
| #idp.authn.fudispasskeys.subjectDecorator= |
| #idp.authn.fudispasskeys.errorMessageFunction = DefaultPasswordErrorFunction |
| #idp.authn.fudispasskeys.genericMessageID = authn |
| #idp.authn.fudispasskeys.addDefaultPrincipals=true |
| #idp.authn.fudispasskeys.trimUsernamePrincipal=true |
| #idp.authn.fudispasskeys.lowercaseUsernamePrincipal=false |
| #idp.authn.fudispasskeys.uppercaseUsernamePrincipal=false |
| #idp.authn.fudispasskeys.supportedPrincipals= \ |
| # saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:InternetProtocol, \ |
| # saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport, \ |
| # saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:Password, \ |
| # saml1/urn:oasis:names:tc:SAML:1.0:am:password, \ |
| # saml2/urn:de:zedat:fudis:SAML:2.0:ac:classes:CR |
| </file> |
| |
| ===== Logging ===== |
Um detaillierte Logging-Informationen vom fudiscr-Plugin zu erhalten, kann die folgende Zeile in ''%{idp.home}/conf/logback.xml'' ergänzt werden: | Um detaillierte Logging-Informationen vom fudiscr-Plugin zu erhalten, kann die folgende Zeile in ''%{idp.home}/conf/logback.xml'' ergänzt werden: |
<file xml> | <file xml> |
| <logger name="de.fu.dis" level="DEBUG"/> |
<logger name="de.zedat.fudis" level="DEBUG"/> | <logger name="de.zedat.fudis" level="DEBUG"/> |
</file> | </file> |
Sollen alle API-Anfragen gegen privacyIDEA separat protokolliert werden, so wird folgende zusätzliche Konfiguration vorgeschlagen: | Sollen alle API-Anfragen gegen privacyIDEA separat protokolliert werden, so wird folgende zusätzliche Konfiguration vorgeschlagen: |
<file xml> | <file xml> |
| <logger name="de.fu.dis.rest.interceptors" level="TRACE"> |
| <appender-ref ref="IDP_FUDIS_REQUEST"/> |
| </logger> |
<logger name="de.zedat.fudis.rest.interceptors" level="TRACE"> | <logger name="de.zedat.fudis.rest.interceptors" level="TRACE"> |
<appender-ref ref="IDP_FUDIS_REQUEST"/> | <appender-ref ref="IDP_FUDIS_REQUEST"/> |
| </logger> |
| <logger name="de.fu.dis.edumfa.client" level="WARN"> |
| <appender-ref ref="IDP_FUDIS_REQUEST"/> |
</logger> | </logger> |
<logger name="de.zedat.fudis.privacyidea.client" level="WARN"> | <logger name="de.zedat.fudis.privacyidea.client" level="WARN"> |
<appender-ref ref="IDP_FUDIS_REQUEST"/> | <appender-ref ref="IDP_FUDIS_REQUEST"/> |
</logger> | </logger> |
| |
</appender> | </appender> |
</file> | </file> |
==== Subject Canonicalization ==== | \\ |
Als Zusatzangebot kann für den Prozess der [[https://shibboleth.atlassian.net/wiki/spaces/IDP4/pages/1265631874/SubjectCanonicalization|SubjectCanonicalization]] im Shibboleth Identity Provider ein Flow auf Basis von ''de.zedat.fudis.shibboleth.idp.plugin.authn.fudiscr.domain.ChallengeResponseTokenIdPrincipal'' aktiviert werden. Dieser vom fudiscr-Plugin erzeugte zusätzliche Principal enthält die ID/Seriennummer des erfolgreich verwendeten Token. | |
| |
Um den Flow zu aktivieren, muss in der Konfigurationsdatei ''%{idp.home}/conf/c14n/subject-c14n.xml'' die Referenz ''<ref bean="c14n/fudiscr" />'' in die Liste ''shibboleth.PostLoginSubjectCanonicalizationFlows'' aufgenommen werden. | ===== Erweiterung für Fortinet (FortiAuthenticator) ==== |
| Die Erweiterung für Fortinet unterstützt aktuell die Token-Typen //FortiToken (Mobile und Hardware)//, //SMS// und //E-Mail//. //FIDO2 (WebAuthn)// wird aktuell von der FortiAuthenticator API nicht unterstützt. |
| |
Zusätzlich können wie für andere Principals Transformationsoptionen z.B.in ''%{idp.home}/conf/c14n/subject-c14n.properties'' angegeben werden: | Die Erweiterung steht unter der Apache 2.0 Lizenz und wird von der DAASI International GmbH [[https://gitlab.daasi.de/shibboleth-identity-provider/shibboleth-idp-plugin-authn-fudiscr-fortinetclient|hier]] bereitgestellt. DAASI bietet für die Erweiterung auch Softwarepflegeverträge an. Anfragen sind bitte an [[info@daasi.de|info@daasi.de]] zu senden. |
<file properties> | \\ |
idp.c14n.fudiscr.lowercase=false | |
idp.c14n.fudiscr.uppercase=false | |
idp.c14n.fudiscr.trim=true | |
</file> | |
===== FIDO2 Userless ===== | |
Mit der aktuellen Testversion 1.4.0 wurde in Zusammenarbeit mit der Hochschule München ein neues Authentifizierungsverfahren eingeführt. Weitere Details folgen in Kürze. | |
| |
===== Weitere Materialien ===== | ===== Weitere Materialien ===== |
| |
===== Quellcode ===== | ===== Quellcode ===== |
Hochschulen und andere öffentliche Einrichtungen erhalten auf Anfrage Zugriff auf den Quellcode. Bitte senden Sie hierfür eine E-Mail an [[fudis@zedat.fu-berlin.de|fudis@zedat.fu-berlin.de]]. Es wird daran gearbeitet, sämtliche Komponenten des fudiscr-Plugins unter der Apache 2.0 Lizenz zu veröffentlichen. Wir bitten um Geduld. | Hochschulen und andere öffentliche Einrichtungen erhalten auf Anfrage Zugriff auf den Quellcode. Bitte senden Sie hierfür eine E-Mail an [[fudis@fu-berlin.de|fudis@fu-berlin.de]]. Es wird daran gearbeitet, sämtliche Komponenten des fudiscr-Plugins unter der Apache 2.0 Lizenz zu veröffentlichen. Wir bitten (weiterhin) um Geduld. |
===== Kontakt ===== | ===== Kontakt ===== |
Fehler, Fragen, Anregungen etc. bitte per E-Mail an [[fudis@zedat.fu-berlin.de|fudis@zedat.fu-berlin.de]] senden. | Fehler, Fragen, Anregungen etc. bitte per E-Mail an [[fudis@fu-berlin.de|fudis@fu-berlin.de]] senden. |