Authentication

From MediaWiki.org

Jump to: navigation, search
  
This page was recently moved from MetaWiki.
The page probably requires cleanup - please feel free to help out. Remove this template once that is done.
Some or all of the information on this page is inconsistent, irrelevant or confusing.
Please help clean it up if you are able.
by Ryan Lane
  • Suggestion II: Web server Authentication, and PHP/Pear::Auth. that solves the problem with LDAP authentication because if your webserver can LDAP/PAM whatever
by Bill Clark
  • See also: Apache Basic Auth for those looking to use an existing basic-auth in conjunction with MediaWiki.
  • See Extension:AutomaticREMOTE_USER for transparent authentication using Apache's REMOTE_USER variable. (e.g. useful for pages protected by .htaccess) This has also been hacked to work with Windows IIS 6.0(non-Apache) to provide external authentication using Oracle Core ID (Netpoint Oblix) Single Sign-on.
  • See also: SSL authentication extension to use certificates and Apache mod_ssl to login users
  • See also: PwAuthPlugin extension to authenticate using your local system password database
  • see also: API for other ways to authenticate with trough URL

Comments by Ryan (published with his permission) --Tom Gries [mail] 20:20, 4 Nov 2004 (UTC)

It seems to me that our patches are somewhat independent, and use different options in LocalSettings.php. I believe our ideas are two separate but equally useful ones. Bill's idea is to have a webserver (which can already do authentication of various types) authenticate for the wiki, whereas my patch will work with LDAP servers directly and can handle multiple domains simultaneously. My patch also gives the option of using the local database as well as LDAP servers incase a user cares to use the wiki for a transition period, or does not want a user to have an account in LDAP. The use of either patch would depend on what the end user's network (and management/system admins) allow.

If any of us can think of a good way to combine these patches, I'm all for it, but I'm truthfully somewhat ignorant on using webservers for authentication, and the way we could merge these patches in such a way that we would have one set of options in LocalSettings.php that would allow both methods to be used usefully.

I don't personally see a problem with having three different options for authentication though

  1. local database (default),
  2. meta:Web Server authentication (Bill's patch), and
  3. Extension:LDAP Authentication (my patch),
  4. Auto-login / Auto-account-creation by hostname for intranet MediaWikis (patch and flowchart) based on
    1. hostname detection with php: gethostbyaddr() and/or
    2. NTLM authentication to detect a logged-in Windows user by using NTLM HTTP Authentication, see wp:en:NTLM and http://modntlm.sourceforge.net and http://modntlm.jamiekerwick.co.uk/

as they seem like separate ideas.

I have put some short documentation at Extension:LDAP_Authentication and I have linked to it from the roadmap.

Ryan Lane


I'm interested in using mediawiki in conjunction with an external authentication source, namely, Shibboleth[1]. This is a system which allows for distributed single-sign on between institutions and is growing in popularity in the educational sector. Something similar would be well-received in wiki-land, I expect: I for one am sick of signing in at 5-10 seperate mediawiki installations, a centralised login would be a boon.

A quick bit of thinking about what would need to be done:

(This would also be of use for other sign-on technologies such as pubcookie[2]).

  1. Support external HTTP authentication[3], which works roughly like this
    1. user accesses a URI which is defined to be access-controlled by the web server
    2. web server returns 401 (unauthorized), browser asks user for their credentials
    3. credentials returned in an Authorization: header
  2. There would need to be a bit of hacking around account creation: namely, explicit account creation would be disabled entirely, but if shibboleth presents an authenticated user for which mediawiki knows nothing about, it should silently fill out the default account bits for the user.
  3. the login challenge would need to be identifiable by a URI so that an apache <Location> header could be applied to it.

Shibboleth hooks into the web server's authentication magic and directs people off to an external source to authenticate. This external server then communicates back with shibboleth, passing information about the user (from their username to whatever else they've agreed to share). At that point, the username and other info can be provided to mediawiki via the HTTP environment variables, e.g. REMOTE_USER.

(Sorry if this seems a bit unclear!)

Jdowland 13:31, 20 Jun 2005 (UTC)

Someone mentioned PEAR::Auth above: Note that there's also PEAR::Auth_HTTP which, I think, might work in conjunction with shibboleth.
For this purpose (SSO in Wikis, Blogs, Forums) OpenID (http://openid.net) is a very good solution too.



A solution to integrate MediaWiki with external authentication systems is available at http://wiki.case.edu/CaseWiki:External_Authentication. --IndyGreg 18:51, 29 July 2005 (UTC)


How to automatically login to MediaWiki based on REMOTE_USER(authentication via apache).


Poor-mans external Auth (for mediawiki 1.4.7)

I choose yet-another way which is much more simpler; I have an existing LDAP Authentication Infrastructure and use Apache. By default, all our internal websites are protected with mod_auth_ldap.

A prerequisite is, that I ask people to log in with their email-address. To get the username, I split the email address (username@domain.com) and take what is before the "@" later. By that I have both username and email in my session.

If a user connects now Apache takes care of the authentication. This allows me the flexibility I need in terms of giving Access only to people with certain Attributes/Values etc.

When the wiki is started, it has the login user name (= the email address) in the Environment (REMOTE_USER).

If people only want to browse the wiki, they don't have to do anything else.

The editors have to create an account and log in. To make sure that the names of the users in the wiki are complying to what I have in LDAP, I made the Userlogin.php mostly read-only.

It is a step for the user to create the account and click on log-in, but hey, user procedures are good and keep the guys busy ;-)

With a little bit of effort, it should be possible to rewrite Mediawiki to only rely on the REMOTE_USER environment variable. But I don't have the patience and time to do that and this poor-mans' approach is quick and fits fully into my user management system.

This is what I did to Userlogin.php

--- Userlogin.php       2005-08-11 11:02:53.000000000 +0200
+++ Userlogin.php.orig  2005-03-27 18:11:26.000000000 +0200
@@ -24,7 +24,7 @@
                <tr>
                        <td align='right'><label for='wpName'><?php $this->msg('yourname') ?>:</label></td>
                        <td align='left'>
-                               <input tabindex='1' readonly type='text' name="wpName" id="wpName"
+                               <input tabindex='1' type='text' name="wpName" id="wpName"
                                        value="<?php $this->text('name') ?>" size='20' />
                        </td>
                        <td align='left'>
@@ -37,7 +37,7 @@
                <tr>
                        <td align='right'><label for='wpPassword'><?php $this->msg('yourpassword') ?>:</label></td>
                        <td align='left'>
-                               <input tabindex='2' readonly type='password' name="wpPassword" id="wpPassword"
+                               <input tabindex='2' type='password' name="wpPassword" id="wpPassword"
                                        value="<?php $this->text('password') ?>" size='20' />
                        </td>
                        <td align='left'>
@@ -52,7 +52,7 @@
                <tr>
                        <td align='right'><label for='wpRetype'><?php $this->msg('yourpasswordagain') ?>:</label></td>
                        <td align='left'>
-                               <input tabindex='5' readonly type='password' name="wpRetype" id="wpRetype"
+                               <input tabindex='5' type='password' name="wpRetype" id="wpRetype"
                                        value="<?php $this->text('retype') ?>"
                                        size='20' />
                        </td>
@@ -62,7 +62,7 @@
                        <?php if( $this->data['useemail'] ) { ?>
                                <td align='right'><label for='wpEmail'><?php $this->msg('youremail') ?>:</label></td>
                                <td align='left'>
-                                       <input tabindex='7' readonly type='text' name="wpEmail" id="wpEmail"
+                                       <input tabindex='7' type='text' name="wpEmail" id="wpEmail"
                                                value="<?php $this->text('email') ?>" size='20' />
                                </td>
                        <?php } ?>
@@ -106,4 +106,4 @@
        }
 }

-?>
+?>
\ No newline at end of file

And here the changes to SpecialUserlogin.php

--- SpecialUserlogin.php        2005-08-11 10:55:00.000000000 +0200
+++ SpecialUserlogin.php.orig   2005-06-19 04:05:20.000000000 +0200
@@ -404,11 +404,7 @@
                        if ( 0 != $wgUser->getID() ) {
                                $this->mName = $wgUser->getName();
                        } else {
-                               //$this->mName = @$_COOKIE[$wgDBname.'UserName'];
-                               $this->mEmail = getenv("REMOTE_USER");
-                                $pieces=explode("@",getenv("REMOTE_USER"));
-                                $this->mName = $pieces[0];
-
+                               $this->mName = @$_COOKIE[$wgDBname.'UserName'];
                        }
                }

Now, this applies to the Version 1.4.7 but I did it for earlier versions as well; the idea is to inject the REMOTE_USER into the Authentication logic as early as possible and avoid the user to change it by any means. Afterwards, the User DB of Mediawiki is used.

Caveat: If you create your Mediawiki with an admin user which is not in ldap, you have to modify the user db manually to be able to use the administrators functions. As changing an account is somewhat tricky (at least if you spend no time in searching and reading the documentation), I did the following: Use phpmyadmin to access the user_rights table, delete the entry for my personal account, copy the entry for the admin account to my user_id. One of the gurus out there might have an idea on a cleaner way.

[edit] A cleaner way to do

Without Being a Guru at all, I found a pretty neat way to do this on this page. This hack does not only allow automatic login, it also creates a user account for you if you don't have one yet (assuming that if you can pass the htaccess, then you can also see the wiki.)

I will describe here how to proceed.

First of all, copy the file includes/AuthPlugin to includes/Auth_Remote for instance.

Then edit the file Auth_Remote. It has to be a class extending AuthPlugin. Here is its definition:

 * someone logs in who can be authenticated externally.
 */
require_once('AuthPlugin.php');

# class AuthPlugin {
class Auth_Remote extends AuthPlugin
{

Then just delete all the functions within the class and add the following constructor:

        function Auth_Remote()
        {
            if ( strlen($_SERVER['REMOTE_USER']) )
              {
                global $wgExtensionFunctions;
                if (!isset($wgExtensionFunctions))
                  {
                    $wgExtensionFunctions = array();
                  }
                else if (!is_array($wgExtensionFunctions))
                  {
                    $wgExtensionFunctions = array( $wgExtensionFunctions );
                  }
                array_push($wgExtensionFunctions, 'Auth_remote_user_hook');
              }
            return;
        }

Then add the following right after the closing bracket of the class:

function Auth_remote_user_hook()
  {
    global $wgUser;
    global $wgRequest;
    global $_REQUEST;

    // For a few special pages, don't do anything.
    $title = $wgRequest->getVal('title') ;
    if ($title == 'Special:Userlogout' || $title == 'Special:Userlogin')
      {
         return;
      }

    // Do nothing if session is valid
    $wgUser = new User();
    $wgUser->load();
    if ($wgUser->isLoggedIn())
      {
        return;
      }

    $username = $_SERVER['REMOTE_USER'];
    $u = User::newFromName( $username );
    if (is_null($u))
      {
        // Invalid username or some other error -- force login, just return
        return;
      }

    $wgUser = $u;
    if ($u->getId() != 0)
      {
        $_REQUEST['wpName'] = $username;
        // also return, but user is know. set Cookies, et al
        $wgUser->setCookies();
        $wgUser->saveSettings();
        return;
      }

    // Ok, now we need to create a user.
    include ('includes/SpecialUserlogin.php');
    $form = new LoginForm( $wgRequest );
    $form->initUser( $wgUser );
    $wgUser->saveSettings();
}

We then have to set LocalSettings.php to use our new class. Append the following for that:

require_once ('includes/Auth_Remote.php');
$wgAuth = new Auth_Remote ();

You can also set those so that people cannot play around with user accounts and things:

$wgGroupPermissions['*']['createaccount'] = false;
$wgGroupPermissions['*']['edit'] = false;
$wgShowIPinHeader = false;

See also: meta:Access control

Personal tools