User:Otheus/Auto Login via REMOTE USER

REMOTE USER authentication edit

This is for MediaWiki 1.5.5. I believe it makes use of a Hook not present in versions prior to 1.5.3.

Background edit

MediaWiki by default allows anyone via IP or login to see and modify the contents of the Wiki. By default, the login accounts are created and used only within MediaWiki. If a site administrator wishes to integrate a MediaWiki site with an existing user authentication framework, an extension is needed. Most web servers, including Apache, provide several user authentication mechanisms, including basic www-authenticate and public/private key SSL authentication. Once the web server authenticates a user, it sets available a CGI/Server environment variable named REMOTE_USER.

History edit

This extension makes use of an earlier patch provided here. (See history of this page). The previous code base was useful as a starting-point, but flawed in several ways. This version hopes to improve on that patch.

Design edit

When the user first hits the wiki, the web server authenticates the user and sets the REMOTE_USER variable. The MediaWiki code is then invoked. At the end of Setup.php, before any real processing begins, the extension's hook is called. This code depends primarily on the fact that user is always authenticated by the web server prior to any MediaWiki code being executed.

If the user already has an existing, valid MediaWiki session and account, the hook takes no further action. MediaWiki already has what it needs.

If the user has an existing valid MediaWiki account, but not a session, the hook simply ensures that MediaWiki uses the username in REMOTE_USER in creating a session, cookies, etc, and takes no further action.

If the user has not created an account, the hook uses MediaWiki's initUser() function to create an account, and sets various default user-options. See the hook's initUser function to change these default options. The hook then issues a Location directive to the browser, using the same URL that was called. When the browser reloads, the user account has been created, a session is now created, and MediaWiki behaves as normal.

If the user has cookies turned off, they will probably find themselves in an endless redirection loop.

Installation edit

LocalSettings.php edit

Insert the following lines before the closing ?>:

  require_once('extensions/Auth_remoteuser.php');
  $wgAuth = new Auth_remoteuser();

extensions/Auth_remoteuser.php edit

Download and install the code as extensions/Auth_remoteuser.php

Web Server configuration edit

For basic authentication, one can set up a .htaccess as follows:

AuthType Basic
AuthName Wiki
AuthUserFile /etc/passwd-apache
require valid-user

One can employ more sophisticated mechanisms; ie, LDAP, NIS, NIS+, etc, using Apache modules or what-have-you. t

Q&A edit

Q. How can we use LDAP here? and how to configure .htaccess file for same?

A. There is an Apache module that authenticates via PAM. Compile and install this with Apache (instructions included in the tar file). You'll need the following line in pam.d/http (or httpd, not sure)

account    required     pam_unix_auth.so.1 

Uh, or so I hear. I'm using some sort of broken Solaris installation and I had to comment-out the pam_acct_mgmt line in the code. Then (for NIS) I had to break NIS security to make it work. Now, if you are using LDAP via /etc/nsswitch.conf, this should work automatically. Ahem. Finally, you'll need to tweak the .htaccess file. I recommend protecting authentication via SSL, so I have:

<IfDefine SSL>
 # Use PAM for remote-authentication
 # This will authenticate versus 
 # the user's OS-based authentication
 # Note: this is using a hacked version
 # of AuthPam that does not check user credentials
 # because that's broken under solaris yp
 AuthPam_Enabled on
 AuthPam_Fallthrough off
 AuthType Basic
 AuthName "LDAP User Logon"
 require valid-user
</IfDefine>

There there are also apache2 modules named ldap and authnz_ldap:

AuthName "LDAP User Logon"
AuthType Basic
AuthBasicProvider ldap
AuthLDAPURL "ldap://ldap.server.name/dc=some,dc=names,dc=here"
AuthzLDAPAuthoritative off
Require valid-user

or for just one group from ldap:

AuthName "LDAP User Logon"
AuthType Basic
AuthBasicProvider ldap
AuthLDAPURL "ldap://ldap.server.name/dc=some,dc=names,dc=here"
Require ldap-group cn=GROUPNAME,ou=group,dc=some,dc=names,dc=here

Q. The backup script doesnt work?

A. the script maintenance/dumpBackup.php fails because the changed user settings. Try to set the REMOTE_USER environment variable:

REMOTE_USER="wikiusername" php5 dumpBackup.php  --full

Default User Settings edit

See the notes under #initUser().

Secure Server Settings edit

Make sure your server sets HTTPS_KEYSIZE only when in SSL/https mode. If not, change #The hooking function accordingly.

Implementation Details edit

The Hook edit

This extension makes use of the "Hook" at the end of Setup.php. Here you will find the following code:

# Extension setup functions for extensions other than skins
# Entries should be added to this variable during the inclusion
# of the extension file. This allows the extension to perform
# any necessary initialisation in the fully initialised environment
foreach ( $wgExtensionFunctions as $func ) {
        $func();
}

Initialization edit

The module's/extension's initialization code adds the name of the extension's primary workhorse function to $wgExtensionFunctions. If the array doesn't exist or is not an array, it is assumed that it is a single string and then converted into an array. All this is done only if REMOTE_USER is actually set. If it's not set, there is no point to the extension.

AuthPlugin routines edit

Several routines from AuthPlugin must be overridden for correct operation to occur.

  • userExists() must return true always. The method is misleading. It's only called by MediaWiki in determining whether the user exists in the security context, not whether the user is in the MediaWiki database.
  • authenticate() is a tricky one. My code returns true whenever REMOTE_USER is set, false otherwise. One might want anonymous users to see the site, but not be authenticated to make changes. This is why this depends on the REMOTE_USER setting.
  • autoCreate() should always be true. This gets checked only within initUser(), ie, when the Web Server has authenticated a user unknown to the Wiki.
  • strict() is set to true based on the word of the author of the previous version of this extension.
  • modifyUITemplate configures the user interface so that the user does not see configuration options which don't apply to him. I'm not certain this works correctly.

initUser() edit

initUser() -- configure this routine according to your particular environment, including Email address and email domain.

The hooking function edit

  1. If the page requested is either Special:Userlogout or Special:Userlogin, do nothing.
  2. Try to load the User session. If successful, and the User is logged in, do nothing.
  3. Call User::newFromName ( REMOTE_USER ). If the username is invalid, just do nothing.
  4. Set $wgUser to the user info returned from newFromName.
  5. If the getID is non-zero, the user is already known to MediaWiki:
    1. set _REQUEST['wpName'] to the REMOTE_USER (This seems to be necessary from LoginForm())
    2. return
  6. Create a New Wiki User
    1. Create a new LoginForm(). A form isn't actually created, but the constructor includes code that sets up a quasi-global user variable.
    2. Call initUser()
      • wgUser->initUser() will invoke wgAuth->initUser().
      • That's where the user defaults are set. You can also set them here after the call to initUser()
    3. Call wgUser->saveSettings(). This is required to save the settings from above to the database and appears to be a bug in LoginForm::initUser().
    4. Re-create the calling URL and redirect the browser to it. Note: the HTTPS portion has not been tested and may be server-specific!

Code edit

Download from here.