LDAP hub/Migration from extension LDAPAuthentication

From mediawiki.org
Jump to navigation Jump to search

This page holds example configurations of the original Extension:LdapAuthentication and how these need to be rewritten for LDAP Stack.

Full fledged configuration[edit]

Example 1[edit]

  • Allow network based authentication (aka "implicit", e.g. by using Apache's mod_auth_kerb module for Kerberos authentication)
  • Allow form based authentications with local user accounts
  • Allow form based authentications with remote LDAP user accounts
  • Restrict login to certain LDAP user groups
  • Syncronize user info
  • No syncronization of user groups

Given $_SERVER['REMOTE_USER'] = 'someuser@company.local'

Old

require_once( $IP.'/extensions/LdapAuthentication/LdapAuthentication.php' );
$wgLDAPUseLocal = true;
$wgLDAPBaseDNs = [ 'company.local' => 'o=DOMAIN' ];
$wgLDAPDomainNames = [ 'company.local' ];
$wgLDAPSearchAttributes = [ 'company.local' => 'uid' ];
$wgLDAPGroupAttribute = [ 'company.local' => 'member' ];
$wgLDAPRequiredGroups = [ 'company.local' => [ 'cn=WikiAccess,ou=Groups,o=Company' ] ];
$wgLDAPGroupNameAttribute = [ 'company.local' => 'cn' ];
$wgLDAPGroupObjectclass = [ 'company.local' => 'groupOfNames' ];
$wgLDAPGroupUseRetrievedUsername = [ 'company.local' => false ];
$wgLDAPLowerCaseUsername = [ 'company.local' => true ];
$wgLDAPGroupUseFullDN = [ 'company.local' => true ];
$wgLDAPDisableAutoCreate = [ 'company.local' => false ];
$wgLDAPPreferences = [ 'company.local' => [
	'email' => 'mail',
	'realname' => 'fullname'
] ];
$wgLDAPPort = [ 'company.local' => 389);
$wgLDAPEncryptionType = [ 'company.local' => 'clear' ];
$wgLDAPServerNames = [ 'company.local' => 'ldap.company.local' ];
 
$wgAuth = new LdapAuthenticationPlugin();

// Implicit Login
if ( !empty( $_SERVER['REMOTE_USER'] ) ) {
	require_once( $IP.'/extensions/LdapAuthentication/LdapAutoAuthentication.php' );
	$wgLDAPAutoAuthUsername = preg_replace( '|@.*$|', '', $_SERVER['REMOTE_USER'] );
	$wgLDAPAutoAuthDomain = 'company.local';
	AutoAuthSetup();
}

New

wfLoadExtensions( [
	'PluggableAuth',
	'Auth_remoteuser',
	'LDAPProvider',
	'LDAPAuthentication2',
	'LDAPAuthorization',
	'LDAPUserInfo'
] );

$LDAPAuthorizationAutoAuthRemoteUserStringParser = 'username-at-domain';
$LDAPAuthentication2UsernameNormalizer = 'strtolower';
$LDAPAuthentication2AllowLocalLogin = true;
$wgAuthRemoteuserAllowUserSwitch = true;
$wgPluggableAuth_EnableLocalLogin = true;

$wgAuthRemoteuserUserName = function() {
	$user = '';
	if( isset( $_SERVER[ 'REMOTE_USER' ] ) ) {
		$user = strtolower( $_SERVER[ 'REMOTE_USER' ] );
	}

	return $user;
};

$LDAPProviderDomainConfigProvider = function() {
	$config = [
		'company.local' => [
			'connection' => [
				"server" => "ldap.company.local",
				"options" => [
					"LDAP_OPT_DEREF" => 1
				],
				"basedn" => "o=Company",
				"groupbasedn" => "o=Company",
				"userbasedn" => "o=Company",
				"searchattribute" => "uid",
				"usernameattribute" => "uid",
				"realnameattribute" => "fullname",
				"emailattribute" => "mail",
				"grouprequest" => "MediaWiki\\Extension\\LDAPProvider\\UserGroupsRequest\\GroupMember::factory"
			],
			'authorization' => [
				'rules' => [
					'groups' => [
						'required' => [
							'cn=WikiAccess,ou=Groups,o=Company'
						]
					]
				]
			],
			'userinfo' => [
				'attributes-map' => [
					'email' => 'mail',
					'realname' => 'fullname'
				]
			]
		]
	];

	return new \MediaWiki\Extension\LDAPProvider\DomainConfigProvider\InlinePHPArray( $config );
};

Example 2[edit]

LocalSettings.php

<?php

#---------------LDAP---------------

#---------------Extension LDAPProvider---------------
#provides classes and configuration to query data from LDAP resources
wfLoadExtension( 'LDAPProvider' );
$ldapJsonFile = "$IP/extensions/LDAPProvider/docs/ldapprovider.json";
$LDAPProviderDomainConfigProvider = "\\MediaWiki\\Extension\\LDAPProvider\\DomainConfigProvider\\LocalJSONFile::newInstance";
$LDAPProviderDomainConfigs = $ldapJsonFile;
$LDAPProviderDefaultDomain="REDACTED";

#---------------Extension PluggableAuth---------------
#provides a framework for creating and using authentication and authorization extensions
wfLoadExtension( 'PluggableAuth' );
$wgPluggableAuth_EnableAutoLogin = false; #if true, disables the logout option
$wgPluggableAuth_EnableLocalLogin = false;
$wgPluggableAuth_ButtonLabel  = "Login...";

#---------------Extension LDAPAuthentication2---------------
wfLoadExtension( 'LDAPAuthentication2' );
$LDAPAuthentication2AllowLocalLogin = false;

ldapprovider.json

Note that all fields are in lowercase letters, e.g. samaccountname. When using the field names as they are in AD, i.e. sAMAccountname, this error occurs.

{
	"REDACTED": {
		"connection": {
			"server": "SERVER_IP",
			"port": "389",
			"enctype": "clear",
			"user": "REDACTED",
			"pass": "REDACTED",
			"options": {
				"LDAP_OPT_DEREF": 1
			},
			"basedn": "OU=Company,dc=REDACTED,dc=REDACTED",
			"userbasedn": "OU=user,OU=Company,DC=REDACTED,DC=REDACTED",
			"searchattribute": "samaccountname",
			"usernameattribute": "samaccountname",
			"realnameattribute": "displayname",
			"emailattribute": "mail"
		},
		"userinfo": {
			"attributes-map": {
				"email": "mail",
				"realname": "displayname",
				"nickname": "givenname"
			}
		}
	}
}


Example 3 - MediaWiki on CentOS w/ActiveDirectory[edit]

New MediaWiki Server: Mediawiki 1.35 + LDAP Stack

Legacy MediaWiki Server: MediaWiki 1.26.0 + LDAP Auth

LDAP Server: Microsoft Active Directory Server(s) domain.

MediaWiki Server: VMware VM, CentOS 8.2004, SELinux, Firewalld, TLS, MariaDB 10.3, Apache 2.4.37 Virtual Hosts, Remi php 7.3

MediaWiki v1.26.0 was the legacy system we upgraded to v1.35.0. We used forms based auth and originally did not require users to login to view pages, only to edit. In the new system that has changed as now they must login to view or edit. We are still using forms based auth and not any Network or Apache/HTTP/s based user auth. We do use TLS for transport encyrption to/from the Apache Virtual Host/site, all backend services are localhosted.

The TLS setup can catch folks (on linux at least) so I suggest looking into update-ca-trust and follow that. Afaik openssl and the system do not really share trust info per/se and use differnet source folders and such.

I did not post any of the data, database, or OS upgrade info here. Basically I setup an entirely new VM with all new software and just did a database backup and restore, which went ok but there were some issues I had to roll around and figure out. I copied over all the files from the images folder naturally so all the uploads would be there too.

v1.26.0 LdapAuthentication LocalSettings.php[edit]

Relevant LocalSettings.php parts :

  • Note: all actual domain names CostaRica.Net and server names are fictional. Any name conflicts in the real world are purely coincidental and accidental.
#  Note: all actual domain names and server names are fictional. Any name conflicts in the real world are purely coincidental and unintentional.

# already tested on /wiki126 . slightly newer mediawiki but should work just as fine in here.
## Testing LDAP Extension
##

require_once ("$IP/includes/AuthPlugin.php");
require_once ("$IP/extensions/LdapAuthentication/LdapAuthentication.php");

$wgAuth = new LdapAuthenticationPlugin();

$wgLDAPDomainNames = array(
  'CostaRica.Net'
);

$wgLDAPServerNames = array(
  'CostaRica.Net' => 'adsantiago.costarica.net adsanjose.costarica.net adsanmarcos.costarica.net'
);

$wgLDAPSearchStrings = array(
  'CostaRica.Net' => 'COSTARICANET\\USER-NAME'
);

$wgLDAPSearchAttributes = array(
  'CostaRica.Net' => 'sAMAccountName'
);

$wgLDAPBaseDNs = array(
  'CostaRica.Net' => 'DC=costarica,DC=net'
);

$wgLDAPEncryptionType = array(
  'CostaRica.Net' => ''
);

$wgLDAPUseLocal = false;
$wgMinimalPasswordLength = 1;

v1.35.0 LDAPStack LocalSettings.php[edit]

Just the relevant sections needed. I added the logging section I used as it really helped me figure things out.

# LocalSettings.php

# auth and access extensions
wfLoadExtension( 'Auth_remoteuser' );
wfLoadExtension( 'LDAPAuthentication2' );
wfLoadExtension( 'LDAPAuthorization' );
wfLoadExtension( 'LDAPGroups' );
wfLoadExtension( 'LDAPProvider' );
wfLoadExtension( 'LDAPUserInfo' );
#
wfLoadExtension( 'OATHAuth' );
wfLoadExtension( 'PluggableAuth' );
#

#########################################
#
#    Logging / Debugging settings
#    https://www.mediawiki.org/wiki/Manual:How_to_debug#Logging
#    # Enable/Disable logging for debugging.
#    # Verbose but really helped me figure out what was going on as I could tail follow all the logs
#    # as I worked on the config. The online docs were not enough.
#
$wgShowExceptionDetails           = true ;
#$wgDevelopmentWarnings            = true;
## $wgShowDebug                      = false;  # enable some debugging on screen
## $wgDebugToolbar                   = true;  # http://www.mediawiki.org/wiki/Manual:How_to_debug
$wgDebugLogFile                   = "/var/log/mediawiki/debug-${wgDBname}.log" ;
## $wgDBerrorLog                     = "/var/log/mediawiki/dberror.log" ;
$wgRateLimitLog                   = "/var/log/mediawiki/ratelimit.log" ;
// this finally worked. ldap.log got a log from PluggableAuth
$wgDebugLogGroups                 = array(
     'BMWExtension'               => "/var/log/mediawiki/bmwextension.log",
     'resourceloader'             => '/var/log/mediawiki/resourceloader.log',
     'exception'                  => '/var/log/mediawiki/exception.log',
     'error'                      => '/var/log/mediawiki/error.log',
     'exception-json'             => '/var/log/mediawiki/exception.json',
     'Auth_remoteuser'            => '/var/log/mediawiki/Auth_remoteuser.log',
     'LDAPAuthentication2'        => '/var/log/mediawiki/LDAPAuthentication2.log',
     'LDAPAuthorization'          => '/var/log/mediawiki/LDAPAuthorization.log',
     'LDAPGroups'                 => '/var/log/mediawiki/LDAPGroups.log',
     'LDAPUserInfo'               => '/var/log/mediawiki/LDAPUserInfo.log',
     'LDAPProvider'               => '/var/log/mediawiki/LDAPProvider.log',
     'PluggableAuth'              => '/var/log/mediawiki/PluggableAuth.log',
     'LDAP'                       => '/var/log/mediawiki/ldap.log',
     'MediaWiki\\Extension\\LDAPProvider\\Client' => '/var/log/mediawiki/LDAPClient.log'

);

#############################################
##
##       Group Permissions
##
# The following permissions were set based on your choice in the installer
# commented out after initial setup
#$wgGroupPermissions['*']['edit'] = false;
## If account creation by anonymous users is forbidden, then allow
## it to be created automatically (by the extension) with these two settings: .
$wgGroupPermissions['*']['createaccount'] = true;
$wgGroupPermissions['*']['autocreateaccount'] = true;

####################################################################################
##
##    BEGIN LDAP STACK SETUP
##

###############################################
##
##      LDAPGroups
##      https://www.mediawiki.org/wiki/Extension:LDAPGroups
##
# Allows registration of custom group sync mechanisms.
$wgLDAPGroupsSyncMechanismRegistry = "\\MediaWiki\\Extension\\LDAPGroups\\SyncMechanism\\MappedGroups::factory"; 


##########################################
##
##   AuthRemoteUser
##   This is Authorization which is after Authentication
##   https://www.mediawiki.org/wiki/Extension:Auth_remoteuser
##   See Group Permissions Section also
##
$wgAuthRemoteuserDomain = "costarica.net";
$wgAuthRemoteuserMailDomain = "costarica-mailhub.net";
$wgAuthRemoteuserNotify = true; 


###############################################
##
##      DOMAIN Config load
##
### $ldapJsonFile = "/etc/mediawiki/ldapprovider.json"  ;# traditional location. Created new ones w/symlinks to easliy change/modify and add new vhosts auth.
###
### The way I load this allows for more verbose errors in the log as my logging details helped a lot get this configured. Its verbose but it gets things done and I can shut this off and/or enable regular custom logrotate for this.
### 
$ldapJsonFile = "/etc/mediawiki/LDAPProvider/ldapprovider-costarica.net.json" ;
$ldapErrMsg = "LDAPStack Error - LDAP JSON FNF or $IP/extensions/LDAPProvider not found [LDAP-ERR]. : $ldapJsonFile " ;
$ldapConfig = false;
$ldapWriteOkMsgs = false;
if (is_file($ldapJsonFile) && is_dir("$IP/extensions/LDAPProvider")) {
  #
  # this adds a good bit of log messages to files for fcgi and others which show under 'error' heading but it was the only way I could write the file
  # as there is no other easily usable facility I can find in mediawiki to write to a log file but error_log
  #
  if( $ldapWriteOkMsgs ) { error_log("LDAPStack [OK] - JSON in file and the LDAPProvider extensions folder. [LDAP-1000] : $ldapJsonFile "); }

  $testJson = @json_decode(file_get_contents($ldapJsonFile),true);
  if (is_array($testJson)) {
    $ldapConfig = true;

    if( $ldapWriteOkMsgs ) { error_log("LDAPStack OK - Found and validated JSON in file. [LDAP-1001] : $ldapJsonFile "); }
  }
  if (! is_array($testJson)) {
      error_log("LDAPStack Error 103 - $ldapJsonFile syntax error.");
  };
  if (! $ldapConfig ) {
      error_log("LDAPStack Error 102 - Found invalid JSON file or FNF. : $ldapJsonFile ");
  };

};

if (! is_file( $ldapJsonFile ) ) {
    error_log("LDAPStack Error 101 - Found invalid JSON file or FNF. : $ldapJsonFile ");
};

###############################################
##
##     LDAPProvider
##
$LDAPProviderDomainConfigs        = "/etc/mediawiki/LDAPProvider/ldapprovider-costarica.net.json" ;
$LDAPProviderCacheType            = "CACHE_ANYTHING" ;
$LDAPProviderCacheTime            = 500 ;
$LDAPProviderDomainConfigProvider = "\\MediaWiki\\Extension\\LDAPProvider\\DomainConfigProvider\\LocalJSONFile::newInstance" ;
$LDAPProviderDefaultDomain        = 'costarica.net' ;

##############################################
##
##     LDAPAuth
##     See https://www.mediawiki.org/wiki/Extension:LDAPAuthorization
##
$wgLdapAuthDomainNames        = 'costarica.net' ;
$wgLdapAuthIsActiveDirectory  = 'costarica.net';
$wgLdapAuthSearchTree         =  true ;

###############################################
##
##     LDAPAuthentication2
#
#      wfLoadExtension( 'LDAPAuthentication2' );
#      https://www.mediawiki.org/wiki/Extension:LDAPAuthentication2
#      https://www.mediawiki.org/wiki/Extension:LDAPAuthentication2#Configuration
#
$LDAPAuthentication2AllowLocalLogin = true ;
$LDAPAuthentication2UsernameNormalizer = 'strtolower';

################################################
##
##     PluggableAuth
##     extension $wgPluggableAuth which is required for LDAP
##     https://www.mediawiki.org/wiki/Extension:PluggableAuth
##
$wgPluggableAuth_EnableAutoLogin  = true ; 
$wgPluggableAuth_EnableLocalProperties = false ; 
$wgPluggableAuth_ButtonLabel = "Log In"; # defaults to "Login with PluggableAuth "

##
##     END LDAP Stack Settings
##
################################################

### END LocalSettings.php ###

v1.35.0 ldapprovider.json[edit]

New Ldapprovider.json file in /etc .

{
        "CostaRica.Net": {
                "connection": {
                        "server": "adsantiago.costarica.net adsanjose.costarica.net adsanmarcos.costarica.net",
                        "user": "CN=DirectoryUser,OU=SJO,OU=AD Service Accounts,DC=costarica,DC=net",
                        "pass": "oyN&PMFs5]B9",
                        "enctype": "tls ssl",
                        "options": {
                                "LDAP_OPT_DEREF": 1
                        },
                        "basedn": "DC=costarica,DC=net",
                        "groupbasedn": "OU=Security Groups,DC=costarica,DC=net",
                        "userbasedn": "OU=Domain Users,DC=costarica,DC=net",
                        "searchattribute": "samaccountname",
                        "searchstring": "COSTARICANET\\USER-NAME",
                        "usernameattribute": "samaccountname",
                        "realnameattribute": "cn",
                        "emailattribute": "mail",
                        "grouprequest": "MediaWiki\\Extension\\LDAPProvider\\UserGroupsRequest\\GroupMember::factory",
                        "presearchusernamemodifiers": [ "spacestounderscores", "lowercase" ]
                },
                "userinfo": {
                     "attributes-map": {
                           "email"   : "mail",
                           "realname": "cn",
                           "nickname": "sAMAccountName",
                           "language": "preferredLanguage"
                     }
                },
                "authorization": {
                     "rules": {
                           "groups": {
                                "required": [ "CN=SJO_All_Users,OU=SJO,OU=Security Groups,DC=costarica,DC=net" ]
                           }
                     }

                },
                "groupsync": {
                        "locally-managed" : [ "sysop" ],
                        "mechanism"       : "mappedgroups",
                        "mapping"         : {
                            "sjo" : "CN=SJO_All_Users,OU=SJO,OU=Security Groups,DC=costarica,DC=net",
                            "IT"  : "CN=IT Group,OU=SJO,OU=Security Groups,DC=costarica,DC=net"
                        }
                }

        }
}

v1.35.0 Helpful Scripts and Tools[edit]

Along with the mediawiki php scripts to run and test AD Auth and getting groupinfo which are key tests. I created a few of my own outside of the mediawiki realm to help make sure my system itself could do things as needed using required server sub-systems.

These tools are meant to help the Systems Engineer, Sysadmin, or Administrator troubleshoot during setup of MediaWiki LDAPStack and Auth. Using it against Active Directory was my primary use case but they are basically directory indifferent.

You will need to setup your OpenSSL and more importantly your Linux OS TLS setup and add the AD Servers CA to the Trust Anchors in the system.

PHP Script "test-ldap-bind.php"[edit]
<?php

// using ldap bind
$ldaprdn  = "CN=DirectoryUser,OU=SJO,OU=AD Service Accounts,DC=costarica,DC=net";   
$ldappass = 'oyN&PMFs5]B9';  // associated password

// connect to ldap server
$ldapserver = "ldap://adsantiago.costarica.net";
$ldapconn = ldap_connect($ldapserver)
    or die("Could not connect to LDAP server.");

if ($ldapconn) {

    // binding to ldap server
    $ldapbind = ldap_bind($ldapconn, $ldaprdn, $ldappass);

    // verify binding
    if ($ldapbind) {
        echo "LDAP bind successful to $ldapserver as $ldaprdn .";
    } else {
        echo "LDAP bind failed to $ldapserver as $ldaprdn .";
    }

}

    // See https://www.php.net/manual/en/function.ldap-bind.php

?>
PHP Script "test-ldap-starttls.php"[edit]
<?php

   $ldapserver="adsantiago.costarica.net";
   $usr="directoryuser@costarica.net";
   $pwd='oyN&PMFs5]B9';

   $ds=ldap_connect($ldapserver);
   $ldapbind=false;
   if(ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3))
      if(ldap_set_option($ds, LDAP_OPT_REFERRALS, 0))
         if(ldap_start_tls($ds))
               $ldapbind = @ldap_bind($ds, $usr, $pwd);
   ldap_close($ds);
   if(!$ldapbind)
       echo "LDAPBind StartTLS ERROR to $ldapserver as $usr .";
   else
       echo "LDAPBind StartTLS OK to $ldapserver as $usr ." ;

   // See https://www.php.net/manual/en/function.ldap-start-tls.php
?>
PHP Script "test-ldaps-connect.php"[edit]
<?php

// make sure your host is the correct one
// that you issued your secure certificate to
$ldapserver = "ldaps://adsantiago.costarica.net/";

// Connecting to LDAP
$ldapconn = ldap_connect($ldapserver)
          or die("That LDAP-URI was not parseable, or other error (TLS LDAP?) .");

if ($ldapconn) {

    // binding to ldap server
    //  $ldapbind = ldap_bind($ldapconn, $ldaprdn, $ldappass);
    //  or die ("That LDAP-URI was not parseable, or other error (TLS LDAP?) .");

    // verify binding
        echo "Ordinary LDAP/s connection successful to $ldapserver .";
    } else {
        echo "Ordinary LDAP/s connection failed to $ldapserver .";
    }

// See https://www.php.net/manual/en/function.ldap-connect.php

?>
Bourne Shell Script "test-openssl-starttls.sh"[edit]

Test OpenSSL against AD StartTLS:

#!/bin/bash

RETVAL=999
SERVER="adsantiago.costarica.net"
PORT=389

echo "" | openssl s_client -connect "${SERVER}:${PORT}" -starttls ldap -prexit

# echo "" | openssl s_client -connect "${SERVER}:${PORT}" -starttls ldap -prexit -showcerts

# openssl s_client -connect vsp1.example.local:25 -starttls smtp

RETVAL=$?

echo "OpenSSL starttls test return code was: $RETVAL to ${SERVER}:${PORT}" ;

Particular configuration variables[edit]

$wgLDAPAuthAttribute[edit]

Extension:LDAP_Authentication/Configuration_Options#Search_based_login_restriction_configuration_options

Old

$wgLDAPAuthAttribute = array(
  'testLDAPdomain' => '!(nsaccountlock=true)',
);

New

"authorization":
    "attribute-map": {
        "nsaccountlock": "false"
    }

Auth remoteuser (Kerberos auth) with LDAPProvider features[edit]

The example includes a few extensions from LDAPStack, additional packages that you will need to make it works and some extra code that is not included in the documentation (many thanks to Osnard for his support).

Mediawiki 1.33.0 on Ubuntu 16.04. Apache2, PHP7.0, MySQL 5.7, Kerberos authentication.

LDAPProvider 1.0.1, LDAPGroups 1.0.1, LDAPUserInfo 1.0.0

Packages and apache2 mods: kerberos_packages, mod_krb5, php7.0-ldap in my case.

krb5.conf:

[libdefaults]

default_realm = MY.DOMAIN

[realms]

MY.DOMAIN =

{

kdc = server.my.domain:port

kdc = anotherserver.my.domain:port

admin_server = server.my.domain

default_domain = my.domain

}

[domain_realm]

ad-domain.local = MY.DOMAIN

.ad-domain.local = MY.DOMAIN

[login]

krb4_convert = true

krb4_get_tickets = false

apache2.conf:

...
AccessFileName .htaccess
...

.htaccess:

AuthType Kerberos
AuthName "Kerberos Login"
KrbMethodK5Passwd off #Set this to on if you want to allow wiki logons from outside of your domain (manual input).
Krb5Keytab /path/to/krb5_http.keytab
Require user SomeUser@MY.DOMAIN AnotherUser@MY.DOMAIN

LocalSettings.php:

wfLoadExtensions( [
	'Auth_remoteuser',
	'LDAPProvider',
	'LDAPUserInfo',
    'LDAPGroups'
] );

$wgAuthRemoteuserUserNameReplaceFilter = [
    '@MY.DOMAIN$' => ''
];

$LDAPProviderDomainConfigProvider = function() {
        $config = [
                'my.domain' => [
                        'connection' => [
                                "server" => "server.my.domain",
                                "user" => "CN=ldapuser,OU=ADOU,DC=my,DC=domain",
                                "pass" => 'password',
                                "options" => [
                                        "LDAP_OPT_DEREF" => 1
                                ],
                                "grouprequest" => "MediaWiki\\Extension\\LDAPProvider\\UserGroupsRequest\\UserMemberOf::factory",
                                "basedn" => "dc=my,dc=domain",
                                "groupbasedn" => "dc=my,dc=domain",
                                "userbasedn" => "dc=my,dc=domain",
                                "searchattribute" => "samaccountname",
                                "searchstring" => "",
                                "usernameattribute" => "samaccountname",
                                "realnameattribute" => "cn"
                        ],
                        'userinfo' => [
                                "attributes-map" => [
                                        "realname" => "cn"
                                ]
                        ],
                        'groupsync' => [
                                "mechanism" => "mappedgroups",
                                "mapping" => [
                                        "sysop" => "CN=ADGroup,OU=ADOU,dc=my,dc=domain",
                                        "customgroup" => "CN=AnotherADGroup,OU=ADOU,dc=my,dc=domain"
                                ]
                        ]
                ]
        ];
        return new \MediaWiki\Extension\LDAPProvider\DomainConfigProvider\InlinePHPArray( $config );
    }

Line 22 is needed for the LDAPGroup extension to work properly, when the "mappedgroups" mechanism is used.


Add $this->domain = 'my.domain'; return true; (third line) to mediawiki/extensions/LDAPProvider/src/Hook/UserLoadAfterLoadFromSession.php to make the LDAPUserInfo work:

...
protected function findDomainForUser() {
        $this->domain = 'my.domain'; return true;
        $userDomainStore = new UserDomainStore(
        ...

After the settings above the following command line scripts should work:

php extensions/LDAPProvider/maintenance/ShowUserInfo.php --domain my.domain --username SomeUser
php extensions/LDAPProvider/maintenance/ShowUserGroups.php --domain my.domain --username SomeUser

To enable the debug log you can use (LocalSettings.php):

$wgDebugLogGroups['LDAPUserInfo'] = "/tmp/LDAPUserInfo.log";
$wgDebugLogGroups['LDAPGroups'] = "/tmp/LDAPGroups.log";

Very Simple Auth remoteuser Setup[edit]

The example is a very simple setup (that I may evolve at a later date, but is working now).

Mediawiki 1.31.5 on a late 2012 Mac Mini Server running Yosemite (10.10.5) using Server Internal Apache Version 2.4.16, PHP 7.2.21, MySQL 5.6.22

LDAP Hub Extension(s): Auth_remoteuser REL1_33 (I confirm only this one extension)

apache2.conf:

...
AccessFileName .htaccess
...

At the root of my web server file system I have an .htaccess file which connects to my Yosemite Server Open Directory Service as follows:

.htaccess:

AuthBasicProvider ldap
AuthType Basic
AuthName "OpenDirectory"
AuthBasicAuthoritative off
AuthLDAPURL ldap://<server>.local/cn=users,dc=<machine>,dc=lan?uid
AuthLDAPGroupAttribute memberUID
Require valid-user

LocalSettings.php:

# LDAP Authentication
wfLoadExtension( 'Auth_remoteuser' );

One a user authenticates through Apache's .htaccess/OpenDirectory (OD) and gains access to the server, Auth_remoteuser automatically uses the OD username/credentials as the Mediawiki login/username without any prompting or user interaction.

I plan to test/implement user groups so my setup may change substantially at a later date.