Manual:Active Directory Integration

From Linux Web Expert

The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

PluggableAuth with Active-Directory LDAP

With the evolution of Extension:PluggableAuth and LDAP Stack, getting integrated with Active-Directory LDAP is possible, but somewhat complex for new-comers.

A configuration example is provided here, to ease the setup process for those wishing to integrate with MS-AD via LDAP.

Objectives / Aims

  • Configure Mediawiki to use LDAP settings from a single location - ldap.json
  • Users will login with NT-Logon Username, also known as SAMAccountName attribute in a standard AD-schema.

Method

  • LDAP Stack extensions use a number of LDAP attributes to auto-configure the Mediawiki User: SAMAccountName, DisplayName, Mail.
  • LDAP Stack extensions use memberof attribute values to determine if any Security-Groups / Distribution-Lists map to Mediawiki Groups

Versioning

  • LDAP Stack extensions should all be at the same version - Long Term Support (LTS) versions are recommended (e.g. 1.35)
  • Direct downloads can be performed from: https://extdist.wmflabs.org/dist/extensions/


LDAP Stack Extensions are targeted/qualified for MediaWiki LTS releases only.
However, this table helps to determine which extension-releases to use across all recent versions.

MediaWiki Release Recommended Extension Version Test Status Latest Test Date
1.35 (LTS) LDAPxxx_master Tested March 2020

Required Extensions

Required AD Bind-Account

  • Mediawiki uses an LDAP Bind-User / Bind-Password for communications with Active-Directory.
  • Ensure an AD user is provisioned, and grab the LDAP Distinguished Name for the User
  • Sample: CN=MediawikiAuthenticator,OU=Users,DC=acme,DC=com

LDAP Environment

The important configuration entities are detailed below - replace the default-values with your own when tuning ldap.json

Entity Value Comments
Domain acme.com AD-Forest Domain Name
Root Distinguished-Name (DN) dc=acme,dc=com Use MS "Domains and Trusts" console, with Advanced-View enabled, to view domain LDAP attribute (DN)
User Distinguished-Name (DN) dc=acme,dc=com Use MS "Domains and Trusts" console, with Advanced-View enabled, to view domain LDAP attribute (DN)
Bind-Account Distinguished-Name (DN) CN=MediawikiAuthenticator,OU=Users,DC=acme,DC=com Use MS "Domains and Trusts" console, with Advanced-View enabled, to view AD User attribute (DN)

This value is case-sensitive.

Encryption clear No TLS/SSL is used in the example.
User Search Attribute samaccountname Utilise MS-AD samaccountname attribute to locate a single LDAP record.
User Group Membership Attribute memberof Utilise MS-AD memberof attribute, to get list of Group-DNs that user is a member of.

Configuration Example: LDAP Configuration with 1 Group-Mapping

This example works for a small single-domain forest, or multi-domain forest (by using the parent domain).

Install Mediawiki and Extensions

  1. Install PHP, and the php-ldap module (usually available on the same package-manager as PHP)
  2. Install Mediawiki, perform install and update routines.
  3. Install all extensions listed above (Required Extensions) into /extensions/

Prepare ldap.json

Create an LDAP configuration file. For simplicity, we place this new file at /var/www/ldap.json then protect it for reading by the web-server.

touch /var/www/ldap.json
chown www-data:www-data /var/www/ldap.json
chmod 600 /var/www/ldap.json

# use your favourite editor to add the following json
vi /var/www/ldap.json
{
	"acme.com": {
		"connection": {
			"server": "my-domain-controller.acme.com",
			"port": "3269",
			"use-tls": "true",
			"user": "CN=MediawikiAuthenticator,OU=Users,DC=acme,DC=com",
			"pass": "foobar",
			"enctype": "clear",
			"options": {
				"LDAP_OPT_DEREF": 1
			},
			"basedn": "dc=acme,dc=com",
			"userbasedn": "dc=acme,dc=com",
			"groupbasedn": "dc=acme,dc=com",
			"searchattribute": "samaccountname",
			"usernameattribute": "samaccountname",
			"realnameattribute": "cn",
			"emailattribute": "mail",
			"grouprequest": "MediaWiki\\Extension\\LDAPProvider\\UserGroupsRequest\\UserMemberOf::factory",
			"presearchusernamemodifiers": [ "spacestounderscores", "lowercase" ]
		},
		"userinfo": [],
		"authorization": [],
		"groupsync": {
			"mapping": {
				"engineering": "CN=EngineeringCoreTeam,OU=Groups,DC=acme,DC=com",
				"bureaucrat": "CN=Mediawiki Admins,OU=Groups,DC=acme,DC=com",
				"interface-admin": "CN=Mediawiki Admins,OU=Groups,DC=acme,DC=com",
				"sysop": "CN=Mediawiki Admins,OU=Groups,DC=acme,DC=com"
			}
		}
	}
}
  • A critical piece of configuration is the acme.com key in line #2 of the JSON.
  • Replace this with your AD Domain
  • Replace the following values in connection
    • server
    • user
    • pass
    • basedn
    • userbasedn
  • Replace the groupsync -> mapping values with some valid Group-DNs taken from MS "Domains and Trusts" console.
    • This allows you to specify a DN which provides sysop privileges

Tune LocalSettings.php

// Safe IP or not (for bypassing external login via AD)
$safeIPs = array('127.0.0.1','localhost');
$ipsVars = array('HTTP_X_FORWARDED_FOR','HTTP_X_REAL_IP','REMOTE_ADDR');
foreach ($ipsVars as $ipsVar) {
 if (isset($_SERVER[$ipsVar]) && mb_strlen($_SERVER[$ipsVar]) > 3 ) { $wikiRequestIP = $_SERVER[$ipsVar]; break; }
}
$wikiRequestSafe = ( isset($wikiRequestIP ) && ( in_array($wikiRequestIP,$safeIPs) ));


// Create Wiki-Group 'engineering' from default user group
$wgGroupPermissions['engineering'] = $wgGroupPermissions['user'];


// Private Wiki. External LDAP login. Default NS requires login.
$wgEmailConfirmToEdit = false;
$wgGroupPermissions['*']['edit'] = false;
$wgGroupPermissions['*']['read'] = false;
$wgGroupPermissions['*']['createaccount'] = false;
$wgGroupPermissions['sysop']['createaccount'] = false;
$wgGroupPermissions['*']['autocreateaccount'] = true;
$wgBlockDisablesLogin = true;

// Load LDAP Config from JSON
$ldapJsonFile = "$IP/ldap.json";
$ldapConfig = false;
if (is_file($ldapJsonFile) && is_dir("$IP/extensions/LDAPProvider")) {
  $testJson = @json_decode(file_get_contents($ldapJsonFile),true);
  if (is_array($testJson)) {
    $ldapConfig = true;
  } else {
    error_log("Found invalid JSON in file: $IP/ldap.json");
  }
}

// Activate Extension
if ( $ldapConfig ) {

  wfLoadExtension( 'PluggableAuth' );
  wfLoadExtension( 'LDAPProvider' );
  wfLoadExtension( 'LDAPAuthentication2' );
  wfLoadExtension( 'LDAPAuthorization' );
  wfLoadExtension( 'LDAPUserInfo' );
  wfLoadExtension( 'LDAPGroups' );

  $LDAPProviderDomainConfigs = $ldapJsonFile;

  // Force LDAPGroups to sync by choosing a domain (e.g. first JSON object in ldap.json)
  $LDAPProviderDefaultDomain = array_key_first(json_decode(file_get_contents($LDAPProviderDomainConfigs), true));

  $wgPluggableAuth_Config = array(
      array(
        'plugin' => 'LDAPAuthentication2',
        'buttonLabelMessage' => 'pt-login-button',
        'data' => ['domain'=> $LDAPProviderDefaultDomain]
         ),
      array('plugin' => 'LDAPAuthorization'),
    );


  if ($wikiRequestSafe) { $LDAPAuthentication2AllowLocalLogin = true; }
}

Run update.php and test LDAP login

  • After configuring LocalSettings.php and browsing to your Wiki, you should be able to load the public index / Main Page.
  • LDAP login will fail until you run: php /.../mediawiki/maintenance/update.php
  • This is because the LDAP extensions require some new SQL tables.
  • After running update.php, start a fresh browser session and perform a test login.

Debugging

  • If you encounter problems, enable debug and review the output during login.
  • Validate config values and system connectivity using ldapsearch
    ldapsearch -h server -p port -D "user"  -w "pass" -x -v -b "basedn"
    
  • Validate config files and PHP Connectivity to LDAP using CheckLogin and ShowUserInfo located in extensions/LDAPProvider/maintenance/
  • If running SELinux check to see if webserver (Apache) is allowed to connect to LDAP
    # getsebool -a | grep ldap
    authlogin_nsswitch_use_ldap --> off
    httpd_can_connect_ldap --> off
    
    # setsebool -P httpd_can_connect_ldap on
    
    # getsebool -a | grep ldap
    authlogin_nsswitch_use_ldap --> off
    httpd_can_connect_ldap --> on
    
  • Also see Manual:How to debug/Login problems