I had a problem with logging in with LDAP user in my wiki.
That's the first log in of that user, so the same user should be auto-created in the wiki.
But it my case login page was loading few minutes after submit, and then re-load after timeout.
After some debugging I found out that it happens because of eternal recursion, caused by one of onSaveSettings hook handlers.
Let me share some details on that.
In case with auto-created user that PluggableAuth code is called.
It causes call of \User::saveSettings() here, when user real name and email are updated.
\User::saveSettings() executes all hook handlers which are attached to onSaveSettings hook.
In my case one such hook handlers uses \User::newSystemUser( 'MediaWiki default' ) for internal purposes, which seems to be okay.
And here eternal recursion, mentioned above, happens.
MediaWiki checks if user MediaWiki default is a system one. Check is done here
Method \User::isSystemUser() calls \MediaWiki\Auth\AuthManager::userCanAuthenticate( $username ) here which goes through all primary authentication providers and checks if specified user can authenticate with that provider. If user cannot authenticate with any of them - user is considered as system one.
As soon as PluggableAuth primary authentication provider just checks if user basically exists (here) - user is considered as not system user. That seems to be incorrect.
So MediaWiki tries to "steal" that user to use as system one, and at some point calls \User::saveSettings() here.
And that, assuming that we are already in \User::saveSettings() call - causes eternal recursion.
My proposal is to add to PluggableAuth primary authentication provider additional check (when testing if user can authenticate) that specified username is "usable". I mean this check if username is reserved for system user etc.
That's how it's done in \MediaWiki\Auth\LocalPasswordPrimaryAuthenticationProvider, which is used for local login - see
wfLoadExtension( 'PluggableAuth' ); wfLoadExtension( 'LDAPProvider' ); wfLoadExtension( 'LDAPAuthentication2' ); wfLoadExtension( 'LDAPAuthorization' ); wfLoadExtension( 'LDAPUserInfo' ); wfLoadExtension( 'LDAPGroups' ); wfLoadExtension( 'LDAPSyncAll' ); $LDAPProviderDomainConfigs = "$IP/extensions/LDAPProvider/docs/ldapprovider.json"; $wgPluggableAuth_Config['Log In (LDAP 1)'] = [ 'plugin' => 'LDAPAuthentication2', 'data' => [ 'domain' => 'LDAP1' ] ]; $wgPluggableAuth_Config['Log In (LDAP 2)'] = [ 'plugin' => 'LDAPAuthentication2', 'data' => [ 'domain' => 'LDAP2' ] ]; $wgPluggableAuth_EnableLocalLogin = true; $LDAPAuthentication2AllowLocalLogin = true;