feat: OIDC/OAuth2 authentication integration for Horde base#110
feat: OIDC/OAuth2 authentication integration for Horde base#110jcdelepine wants to merge 2 commits into
Conversation
jcdelepine
commented
Jun 15, 2026
login.php handled logout logic directly (CSRF check, clearAuth, session setup, redirect). LoginService.performLogout() already encapsulates all of this. Delegate to it so logout behaviour is consistent whether the request comes from login.php or from the modern routing stack (ResponsiveLogoutController). Pre-logout handlers registered in LoginService now run on all logout paths, not just those going through the responsive stack.
Wires the OIDC auth driver (horde/Core) into the Horde base application: - OAuthLoginController: accept GET in addition to POST to support automatic redirect from login.php to the IdP. - login.php: auto-redirect to the configured OIDC provider when auth.driver = oidc and auth.params.redirect_provider is set. Redirects on all logout reasons except explicit auth failures (REASON_BADLOGIN, REASON_FAILED, REASON_LOCKED). - LoginServiceFactory: register OidcPreLogoutHandler as a pre-logout handler when the auth driver is oidc. - LoginService::performLogout(): aggregate redirect URLs from pre-logout handlers; handler redirect takes priority over redirect_on_logout config. - OAuthAccountController: resolve a human-readable Horde username from OIDC userinfo claims (preferred_username, uid, login, email); store tokens for XOAUTH2 hooks; filter login.php as post-login redirect destination. - OAuthTokenRepositoryFactory: SQL-backed token repository. - Admin UI: OIDC-specific provider fields (logout strategy, SLO endpoints, XOAUTH2 domain). - conf.xml: OIDC auth driver configuration and OAuth/OIDC token storage tab. - Migration 3: add OIDC-specific columns to horde_oauth_providers. - hooks.php.dist: smtp_credentials and backchannel logout route. Depends on: - horde/Core: OIDC integration (PR ##160) - horde/base refactor/login-logout-delegate-to-service (PR horde#109)
|
As anticipated in #109 - This is somewhat more complicated to handle than the previous PRs on the Oauth library itself. Different architecturesYour model of integrating OIDC works a bit different than what we started to implement. I understand yours already works correctly for your install and delivers OAUTH (for UI login) and XOAUTH (for backend login) and a seamless integration. That makes it a bit hard for me to defend wanting to do things a bit different. Fundamentally, the upstream model makes OAuth 2.0 / OIDC an alternative to an Auth driver. Your model makes it an auth driver. In our model, OIDC capabilities (beyond "login to horde") can be added to apps and services individually and independent of login method. I.e. we can drive service login to Twitter, Github, Mastodon, Google Calendar ... independent of how to login to Horde. At the moment many of the necessary changes in horde are not yet implemented, i.e. activesync and caldav/carddav backends with OAuth 2.0 support. Gaps when OIDC is the auth backend
Cherry PickingI would like to take a lot of your PRs' supporting code because it does mostly what we need to do across both models. UsernameAs an opt-in mechanism creating/matching an auth backend username to an attribute provided by the IdP would also work in the upstream concept. Compromise on OAuth Login driverI see there's room for the OAuth Login driver as the primary/only login mechanism for some installations. Horde's login.php will forward to the IdP screen transparently. This will however hide mode selection and language selection as well as the secondfactor UI. TimelineI already stretched the Horde 6.0 Stable Release timeline for some last minute fixes to the cache and activesync codebase. I would rather not stretch much further. @TDannhauer How do you see this? This could easily be an addition for an early horde/base 6.1 as it's a major feature. |
|
To be honest, I prefer a soon release of Horde. Reading the techn question being a Auth driver or beeing an Alternative to an with driver: what is the technical difference? Is adding another "Module Type" worth it? |
|
@ralflang @TDannhauer Thank you for the detailed feedback. I understand the architectural Looking at what actually blocked me: when logging in via OAuth with a The root cause is that IMP_Auth::_canAutoLogin() only attempts XOAUTH2 This would allow the hook infrastructure (OidcHookHelper, Does this direction make sense to you? |
|
Yes, this direction makes sense to me. Allow me some time to look into how we can best integrate what your hooks do with the federated approach. @TDannhauer There is quite some difference. With OIDC as the "auth driver" it will be responsible for all aspects of user handling and everything OIDC naturally cannot do will be unaccessible. With the model we designed for, we can have both "real users of this platform" and "collaborators/privileged guests". We can also allow social login from different platforms (github, google, university internal OIDC) while still having one specific account. The main problem is we historically used a concept of "application auth" (which delegates nicely to horde auth most of the time) which defined both if the user can use the application and how to login to backends (smtp, imap, sieve, ldap to some degree, gollem samba backends, ...) and increasingly this is model doesn't fit very well. These days many services and resources horde needs to access live in cloud platforms which don't want username/password style logins. They want Oauth2.0/OIDC (everything google calendar/tasks/adressbook, social media, billing platforms) or XOauth (Imap, SMTP, ... ) which is OAuth but funneled into a traditional protocol's password field. |