Showing posts with label Mediawiki. Show all posts
Showing posts with label Mediawiki. Show all posts

Tuesday, March 11, 2008

LDAP Authentication in Mediawiki

LDAP Authentication in Mediawiki isn't terribly hard, and it's so very worth it. This post shows how one implementation succeeded, and hopefully it'll help with yours. I have to say that I'm a little hesitant to post this entry, as many people have done so, and inevitably, the post becomes dated, full of deprecated and even downright wrong information. So one runs the risk in the end of being more of a hindrance than a help. So: caveat emptor. I decided in the end to write this because it took a very long time to implement this very useful extension to MediaWiki, and I hope my process will help others in their own implementation. Having said that, one really should check out all of the work Ryan Lane has done and continues to do in writing and supporting this excellent extension. The main page for the extension can be found here. These instructions were written as we implemented version 1.1g, which is one release behind the (as of this writing) current version of 1.2a. Having got that behind us, I hope this is helpful to you:

LDAP Authentication

This is a big one. It can be got from the MediaWiki Extensions Site. The instructions are pretty tough to follow, but it does work.
Here are our settings in LocalSettings.php, in which the user is authenticated against the domain, and all users except those in a select group are disallowed from logging in.

A note about SSL encryption

SSL encryption is necessary to ensure this is a secure process. Especially given that we're talking about domain usernames and passwords. So first, make sure that the apache server is requiring https when accessing the wiki. Second, for the SSL piece of the LDAP authentication to work, the wiki server has to recognize and trust the root CA of the LDAP server (or, in our case, the LDAP virtual IP fronted by a netscaler device). I hope to have instructions on doing this piece posted soon. In any case, please do this before going further.

LocalSettings.php Contents

#LDAP authentication require_once( "$IP/extensions/LdapAuthentication.php" );
#$wgLDAPDebug = 6;
$wgAuth = new LdapAuthenticationPlugin();
$wgLDAPDomainNames = array( "DOMAINNAME");
$wgLDAPServerNames = array( "DOMAINNAME"=>"ldapserver.FQDN" );
$wgLDAPSearchStrings = array( "domainname"=>"DOMAINNAME\\USER-NAME" );
$wgLDAPEncryptionType = array( "domainname"=>"ssl" );
$wgLDAPUseLocal = false;
$wgMinimalPasswordLength = 1;
$wgLDAPBaseDNs = array( "domainname"=>"dc=tcu,dc=edu" );
$wgLDAPSearchAttributes = array( "domainname"=>"sAMAccountName" );
 #Everything above is for simple LDAP authentication; the stuff below is for group syncronization
#DNs in $wgLDAPRequiredGroups must be lowercase, as search result attribute values are...
$wgLDAPRequiredGroups = array( "domainname"=>array("Fully qualified LDAP cn structure goes here") );
$wgLDAPGroupUseFullDN = array( "domainname"=>true );
$wgLDAPLowerCaseUsername = array( "domainname"=>true, );
$wgLDAPGroupObjectclass = array( "domainname"=>"group" );
$wgLDAPGroupAttribute = array( "domainname"=>"member" );
$wgLDAPGroupSearchNestedGroups = array( "domainname"=>true );
$wgLDAPUseLDAPGroups = array( "domainname"=>"true" );
$wgLDAPGroupNameAttribute = array( "domainname"=>"cn" );
 #Adding new groups to the list of possible groups. This value (the group name)
#also needs to be added to the user_groups table in the database. That happens manually.
$wgGroupPermissions['groupname']['edit']= true;

The first bit should be pretty self-explanatory: load the extension, then set the basic variables as specific to your environment. In the examples here, I have used "domainname" and "DOMAINNAME" instead of our true domain name. Case matters here, so stay sharp! Note that the $wgLDAPBaseDNs variable is important; it must be correct. In most cases, this is the final bit of your domain name. For instance, if my domain is example.com, my base DN is also example.com.
Likewise, $wgLDAPRequiredGroups is very specific, and if it's not just right, the whole thing will break. Note that ldapsearch--a piece of openssl--can be an extremely useful tool in determining the correct settings for all of this. If you're using linux, you very likely already will have this tool. If you're using Windows, dsget is an equivalent (as a part of Windows Server) that can really help you out of a jam. Many will recommend a web-base ldap browser, but, honestly, I think the command-line tools like ldapsearch and dsget are much easier to use and set up.
If you're having difficulty, uncomment the $wgLDAPDebug line, and it'll provide a lot of useful debugging information within the browser session.

User Rights Management

User rights management is done through groups. We use the domain groups for this purpose, but it's also necessary to tell MediaWiki about the groups, and how we'll use them. This is done in a single step:
Defining group rights
Edit the LocalSettings.php file and add lines as below:
## The following three lines disable anonymous access $wgGroupPermissions['*' ]['createaccount'] = false;
$wgGroupPermissions['*' ]['read'] = false;
$wgGroupPermissions['*' ]['edit'] = false;
$wgGroupPermissions['tcudba']['edit'] = true;
$wgGroupPermissions['user' ]['move'] = false;
$wgGroupPermissions['user' ]['read'] = true;
$wgGroupPermissions['user' ]['edit'] = false;
$wgGroupPermissions['user' ]['upload'] = false;
In the above example, the default group (user) only can read articles. Those who have not authenticated (*) cannot do anything in the wiki. Those in TCUDBA can edit documents.
There are a variety of possible permissions, which are detailed here. The table below shows a few of the more relevant permissions:
Permission Description
read allows viewing pages not defined in $wgWhitelistRead
edit allows editing unprotected pages.
createpage allows the creation of new pages (requires the edit right).
move allows renaming page titles.
upload allows the creation of new images and files.
createaccount allows the creation of new user accounts.
delete allows the deletion of edits and pages.

Modifying User Groups

An easy way to modify the Mediawiki database is to use PHPmyAdmin. Of course, whether you use a GUI or the command line, the data to modify is the same.
After logging in to phpmyadmin, select the WIKIDB database on the left. Then select the user_groups table and click on the browse button. You'll see the userid and group name of all the users. Note that the userid is a number; you have to use the users table to find out which userid corresponds to which username. Use this method to get back as a sysop in the wiki if you've accidentally removed yourself from that group. If you're still a sysop, you simply can use the special:userrights page.

Troubleshooting

If you receive the error basedn is not set for this type of entry, trying to get the default basedn, that means that the $wgLDAPBaseDNs variable isn't set correctly. At the time of this writing, the correct value for that is
$wgLDAPBaseDNs = array( "tcu"=>"dc=tcu,dc=edu" );
The following commands also can be helpful in determining if your system is set up correctly:
ldapsearch -x -D @TCU -W -b "dc=tcu,dc=edu" "sAMAccountName=" -H ldaps://ldap.example.com
openssl s_client -connect ldap.example.com:636

Manually Adding a User to a Group in Mediawiki

If you've locked yourself out of MediaWiki administration, say, by implementing LDAP authentication, this shows you how to add a user to MediaWiki groups by editing the security tables in the database. User rights are stored in a MySQL table called user_groups. Usually you'll find it's got the wiki prefix so to give a user with the user_id of 1 bureaucrat privileges in the system wiki, use the command:
insert into user_groups values(1,'bureaucrat');

The other 'power' group is sysop:

insert into user_groups values(1,'sysop');

To find out which user_id you want to use, execute the following:

select * from user
Note that you'll need to prefix the table names with a prefix, if you set up your wiki to use one.