enhancement
major
minor
major
minor
minor
#29624
SSO-Login ohne registrierten Benutzeraccount: konfigurierbare Hinweisseite (ApplicationPages.unknownAccountPage) statt Login-Maske, mit Standardseiten für die klassische und die React-Oberfläche
Für das SingleSignOn (SSO) in Verbindung mit TL-Anwendungen muss der Benutzer bereits in der jeweiligen TL-Anwendung registriert sein.
Es kann daher vorkommen, dass ein Benutzer vom SSO-Service erfolgreich authentifiziert wurde, in der aufgerufenen TL-Anwendung jedoch kein entsprechender Benutzer vorhanden ist.
Auf Ebene des SSO-Services liegt in diesem Fall kein Fehler vor, da die Authentifizierung mit gültigen Zugangsdaten erfolgreich durchgeführt wurde. Erst innerhalb der TL-Anwendung kann festgestellt werden, dass für den authentifizierten Benutzer kein entsprechender Benutzeraccount existiert und der Login daher nicht durchgeführt werden kann.
Aktuelles Verhalten
Aktuell wird der Benutzer in diesem Fall auf die TL-interne Loginmaske weitergeleitet.
Das verleitet dazu sich mit den SSO-Zugangdaten erneut anzumelden. Eine Anmeldung über die TL-interne Loginmaske ist für einen SSO-Benutzer nicht möglich bzw. nicht vorgesehen.
Dadurch erhält der Benutzer keine geeignete Rückmeldung darüber, warum die Anmeldung nicht erfolgreich abgeschlossen werden kann.
Anforderung
Für diesen Fall muss eine geeignete Möglichkeit geschaffen werden, dem Benutzer verständlich mitzuteilen, dass er zwar erfolgreich über SSO authentifiziert wurde, jedoch in der aufgerufenen TL-Anwendung nicht registriert ist.
Beispielsweise soll die TL-Anwendung den Benutzer in diesem Fall auf eine entsprechende JSP-Seite weiterleiten können. Diese Seite soll eine verständliche Hinweismeldung anzeigen, z. B.:
Die Anmeldung war erfolgreich. Sie sind jedoch für diese Anwendung nicht registriert. Bitte wenden Sie sich an den zuständigen Administrator.
Die technische Möglichkeit für einen solchen Redirect ist aktuell nicht gegeben. Die existierende Konfigurationsoption loginRetrySSO greift in diesem Fall nicht.
Analyse
Der ExternalAuthenticationServlet (Basis aller externen Anmeldungen: pac4j/OIDC, J2EE-Remote-User) behandelt alle LoginDeniedException`s gleich und leitet per Forward auf die Seite `loginRetrySSO (Standard: die Login-Maske; mit pac4j-direct-login sogar wieder das SSO-Servlet). Der Fall „authentifiziert, aber kein Account“ entsteht in ExternalUserMapping.findAccount und ist dort nicht von anderen Ablehnungen unterscheidbar. In der React-Oberfläche (tl-layout-view, loginRetrySSO=/view/) landet der Benutzer ebenso kommentarlos auf der Login-Seite.
Lösung
Kern (klassische Oberfläche):
- Neue Ausnahme Login.UnknownAccountException (Unterklasse von LoginDeniedException) mit dem externen Anmeldenamen; ExternalUserMapping.findAccount wirft sie, wenn kein (lebender) Account zum externen Namen existiert. Passwort-Anmeldungen (LoginCredentials) und die LDAP-Geräteprüfung bleiben unverändert eine allgemeine Ablehnung, damit die Existenz von Accounts nicht über die Login-Maske ausgeforscht werden kann.
- Neue Konfigurationsoption unknownAccountPage in ApplicationPages$Config: die Seite, auf die ein extern authentifizierter Benutzer ohne Account umgeleitet wird. Der ExternalAuthenticationServlet fängt die neue Ausnahme vor der allgemeinen Ablehnung und leitet per Redirect auf diese Seite um, mit dem externen Anmeldenamen als URL-Parameter. Ein Redirect (statt Forward) entfernt außerdem die OIDC-Callback-URL aus der Adresszeile, sodass ein Neuladen den Autorisierungscode nicht erneut einreicht. Der bisherige Weg über loginRetrySSO für alle anderen Fehler bleibt bestehen.
- Standardseite /jsp/main/LoginErrorPage_unknownAccount.jsp: Logo, Überschrift, Hinweistext mit dem Anmeldenamen („Die Anmeldung als ‚…‘ war erfolgreich. Sie sind jedoch für diese Anwendung nicht registriert. Bitte wenden Sie sich an den zuständigen Administrator.“) und Schaltfläche zur Anmeldeseite, gestaltet wie die Logout-Seite; das Stylesheet der Logout-Seite wird dafür in eine gemeinsame statische CSS-Datei ausgelagert.
React-Oberfläche (tl-layout-view):
- Eigene View unknown-account.view.xml (Karte mit Hinweistext und Anmeldenamen, Link zurück zur Anwendung), ohne JSP. Das Modul setzt unknownAccountPage auf /view/unknown-account.view.xml und registriert die View als Einstiegspunkt (entry-point).
- Einstiegspunkte in ViewConfig erhalten das Kennzeichen anonymous: Ein so gekennzeichneter Einstiegspunkt wird auch einer Sitzung ohne Account angezeigt, anstelle der konfigurierten login-view. Das ist nötig, weil eine Anwendung mit login-view sonst jeder anonymen Sitzung ausschließlich die Login-Seite zeigt.
Verifikation: Tests in TestExternalAuthenticationServlet (unbekannter Account → Redirect auf die konfigurierte Seite mit Namensparameter; allgemeine Ablehnung → weiterhin loginRetrySSO; findAccount wirft die neue Ausnahme) und für ViewServlet.resolveViewPath mit dem anonymous-Kennzeichen; manuelle Prüfung der Seiten in tl-demo und tl-demo-react.