Extension talk:Shibboleth Authentication

Persistent-id support
Hello,

I have made some changes on this extension to make it support persistent-id. It is now a proof-of-concept, so although it works fine in my test enviroment (MW 1.15.3), if you are interested in, I appreciate if you contribute in developing.

The code, and some comments: https://wiki.aai.niif.hu/index.php/MediawikiShibAuthWithPersistentID

best regards, Tamas

MW 1.15rc1

 * the function ShibUpdateTheUser($existing, &$user) that you add in Localsettings.php to update the user information should have a return parameter: "return true;" at the end of the function
 * the plugin registers itself in the "UserLoadFromSession" hook, but that is too early in the login process. This hook is executed before Mediawiki tries to login using existing session. The ShibUserLoadFromSession function looks if the user is already loaded from session, but that never happens, so the user is logged in every time from database. If you use the hook "UserLoadAfterLoadFromSession", session login works again. This code was probably changed in Mediawiki 1.13? Only tested on MW1.15rc1
 * after this fix, if you access a page the first time, it will show a "not logged in" message. After a refresh it works. any ideas?

--- extensions/ShibAuthPlugin.php   (revision 33) +++ extensions/ShibAuthPlugin.php   (working copy)

function ShibGetAuthHook { global $wgVersion; if (strcmp($wgVersion, "1.13") >= 0) { - return 'UserLoadFromSession'; + return 'UserLoadAfterLoadFromSession'; } else { return 'AutoAuthenticate'; }

ShibUserLoadFromSession($user, true); } /* Tries to be magical about when to log in users and when not to. */ -function ShibUserLoadFromSession($user, &$result) +function ShibUserLoadAfterLoadFromSession($user) { global $wgContLang; global $wgAuth;

Peterjacobs 16:32, 8 June 2009 (UTC)

Problem (MW 1.13) - How can I disable automatic user account creation?
I've disabled account creation except by sysops using the setting:


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

Using the ShibAuthPlugin though, anyone logging in using this feature automatically gets a local account created. Is there any way to get the plugin to adhere to the $wgGroupPermissions['*']['createaccount'] = false setting? Or is there any other way to stop the shibauthplugin from automatically creating the account?

Matt - October 8, 2008

Hi Matt,

I see 2 possible (altough both untested) options:
 * make the autoCreate function return false
 * Take a look at the if-construction below 'Is the user already in the database?'. Add an else case that returns false.

--Stevel 09:27, 10 November 2008 (UTC)

MW 1.3: Add user->setupsession
I too had the session problem...wish I would have read the discussion page first. Adding $user->setupSession;

Fixes the problem

And 13:41, 6 February 2009 (UTC) Note that the above has been deprecated in favour of wfSetupSession.

Problems with MW 1.13
I have problems after upgrading to MW 1.13 --Bajnokk 12:20, 30 August 2008 (UTC)
 * User.php requires a session_start at line 2111, if session hasn't been started. (I'm not sure, what goes wrong there)
 * SpecialUserlogin.php has been moved to specials/ directory
 * LoginForm->initUser requires a second (boolean) parameter, that's just a warning.
 * On a new user login (which should result in automatic account creation) I get the following error: . And indeed, User->mPassword is not set, nor are other fields (mNewpassword, mToken, etc). I can not circumvent that last one easily, so I'd appreciate your help.

I've made some changes to the extension to address the problems you described. Only about the session_start problem I don't know what's happening. --Stevel 14:19, 1 September 2008 (UTC)
 * Something is still wrong with automatic user creation. Now it tries to add the new user twice, the result is "Duplicate entry" (it seems that the users' session isn't started properly after creation and it tries to add him again)
 * About the first (session_start) problem: I still get a PHP fatal error after login I can only get through if I add an   there, but it clearly isn't the solution. Session should be started before, or maybe I have wrong configuration? It might be the cause of other problems as well, don't know. Thanks!


 * Fix for "Duplicate entry" error: capitalize the first char of the username in LocalSettings.php:

$shib_UN = ucfirst(strtolower($_SERVER['HTTP_EMAIL']));
 * The problem is that MW 1.13 does not capitalize that char automatically when saving the new user but when checking if user exists, sql query is made with capitalized first char and so MW tries to save new user with existing username.
 * Instead of using ucfirst and strtolower I would suggest using User::getCanonicalName because that is whats mediawiki is internaly using and it will also replace underscores (_) with spaces.

Possible fix for the session error
Thanks for this wonderful extension. I don't use it, but I do make heavy use of the SSLAuthPlugin extension that's based on this one.

I recently updated the SSL auth extension for MW 1.13, using the 1.13-specific changes in the Shibboleth extension as a reference. I, too, was encountering the session problem described by Bajnokk in the SSL auth plugin. After debugging for awhile, I think I've found the problem. The new user path calls  before calling , but the existing user path doesn't. You can fix this problem in the Shibboleth extension by adding the following line just before line 353:

--Dhess 04:51, 18 September 2008 (UTC)

= update for mediawiki 1.11 = (code deleted because not needed anymore) "return true;" added in function SSOLinkAdd

= Ammended patch file for MW 1.11.2 = Thanks(!) for Peter Jacobs for the patch. However it did not work for me out of the box. So I fixed the patch (BringBackAA function really) and am including patch instructions below:

Install Patch

 * 1) Create a file called ShibAuthPlugin.patch in your extensions folder.
 * 2) Copy and paste the code below into it.
 * 3) Make a backup of ShibAuthPlugin.php
 * 4) Patch the extension

cd extensions vi ShibAuthPlugin.patch \\ copy and paste code cp ShibAuthPlugin.php ShibAuthPlugin.php.bak patch ShibAuthPlugin.php ShibAuthPlugin.patch

If you need to reverse the patch, just type patch -R ShibAuthPlugin.php ShibAuthPlugin.patch

Patch
--- ShibAuthPlugin.php.orig	2008-03-06 15:02:25.000000000 -0500 +++ ShibAuthPlugin.php.new	2008-03-06 15:17:53.000000000 -0500 @@ -275,7 +275,7 @@ function SSOLinkAdd(&$personal_urls, $ti       if (! isset($shib_Https))               $shib_Https = false;        $pageurl = $title->getLocalUrl; - +        if (!isset($shib_LoginHint))                $shib_LoginHint = "Login via Single Sign-on";

@@ -285,6 +285,7 @@ function SSOLinkAdd(&$personal_urls, $ti                       $shib_AssertionConsumerServiceURL . "/WAYF/" . $shib_WAYF .                        '?target=' . (isset($_SERVER['HTTPS']) ? 'https' : 'http') .                       '://' . $_SERVER['HTTP_HOST'] . $pageurl, ); +		return true; }

/* Kill logout link */ @@ -301,6 +302,7 @@ function SSOActive(&$personal_urls, $tit

if($shib_RN && $shib_map_info) $personal_urls['userpage']['text'] = $shib_RN; +	return true; }

/* Tries to be magical about when to log in users and when not to. */ @@ -329,7 +331,7 @@ function AutoAuth(&$user) if($user->isLoggedIn) {               BringBackAA; -               return; +               return true; }

//Is the user already in the database? @@ -342,12 +344,11 @@ function AutoAuth(&$user) $shib_map_info = $smi; $user->SetupSession; $user->setCookies; -               return; +               return true; }

//Place the hook back (Not strictly necessarily MW Ver >= 1.9) -       BringBackAA; - +       #BringBackAA; //Okay, kick this up a notch then... $user->setName($wgContLang->ucfirst($shib_UN));

@@ -382,8 +383,7 @@ function AutoAuth(&$user) $lf = new LoginForm($wgRequest);

//Place the hook back (Not strictly necessarily MW Ver >= 1.9) -       BringBackAA; - +       #BringBackAA; //And now we clean up our hack if($wgLangUnset == true) { @@ -397,7 +397,7 @@ function AutoAuth(&$user)

//Now we _do_ the black magic $lf->mRemember = false; -       $lf->initUser($user); +       $lf->initUser($user,true);

//Stop pretending now $shib_pretend = false; @@ -418,5 +418,6 @@ function BringBackAA if($value == 'BringBackAA') $wgHooks['AutoAuthenticate'][$key] = 'AutoAuth'; } +	return true; } ?>

--Jonauman 20:59, 6 March 2008 (UTC)

Whats the point of ShibKillAA/ShibBringBackAA?
I can't see why it would fail without those functions, and I can't understand how they are supposed to work. In ShibKillAA we have this line: $wgHooks[ShibGetAuthHook][$key] = 'ShibBringBackAA'; Wouldn't this set the function-hook to ShibBringBackAA, so if there is just one call to the hook returned by ShibGetAuthHook, ShibBringBackAA would be executed and all the hooks would be back?

Yes, this was done to prevent a loop in versions below MW 1.9. It is not needed in higher versions, but still there for compatibility. As MW 1.9 is no longer supported, perhaps it is reasonable to remove this functionality. I'll look in to it for a new version --Stevel 15:14, 16 June 2010 (UTC)

= Bugfix to 1.2.3 Shibboleth Authentication Extension with Mediawiki Debian Lenny ver:1:1.12.0-2lenny3 =

--- ShibAuthPlugin.php.orig	2009-04-29 14:17:36.986114732 +0200 +++ ShibAuthPlugin.php	2009-04-29 14:21:32.918305572 +0200 @@ -323,10 +323,12 @@ } function ShibAutoAuthenticate(&$user) { -	ShibUserLoadFromSession($user, true); +	$res=true; +	ShibUserLoadFromSession($user, $res); +	return $res; } /* Tries to be magical about when to log in users and when not to. */ -function ShibUserLoadFromSession($user, &$result) +function ShibUserLoadFromSession(&$user, &$result) { 	global $wgContLang; global $wgAuth;

= Bug: MW 1.15 and ShibAuthPlugin 1.2.3 =

If a user logs in via Shibboleth Authentication, an entry in mwusers is created. If the user continues to browse the wiki, he'll get error messages like "cannot create user, username already exists" followed by the failed sql-query. It turns out that the "first letter uppercase" policy is the source of this problem.

However, this can be fixed by replacing code line 413 $user->loadDefaults($shib_UN); with $user->loadDefaults($wgContLang->ucfirst($shib_UN)); in the current version.

Maybe this can be merged into the extension code.

Ralf Boehle Hochschule Mittweida - University of Applied Sciences

Thank you - bug is fixed when I replace this line! --62.47.137.125 08:11, 27 August 2009 (UTC)


 * Instead of using $wgContLang->ucfirst I would suggest using User::getCanonicalName because that is whats mediawiki is internaly using and it will also replace underscores (_) with spaces.

Logging via shibboleth currupts/resets user's local password
I don't know if this is by design or not.... but can someone give me some insight into this behavior? I am experiencing this with users that have both a local password and a shibboleth password. If the user first signs in via the local pw they authenticate fine. Then they sign in via shibb and authenticate as well. Now if that same user tries to log in again via their local the wiki keeps saying incorrect pw. Once the local pw is reset by the system and emailed to user they are able to login locally again. However signing in via shibb just starts this cycle again. Any thoughts here?

This is done by design. The rationale behind this is that when a user starts using Shibboleth, he/she will in general continue to use it (as it's a username/password less to remember). So the existing MW username is no longer updated/changed on a regular basis. To prevent attackers from guessing this password, the md5 hash of the password is set to 'nologin'. As this is not a valid hash, no login through the classic MW authentication is possible. If you want to change this behaviour, look at the function updateUser --Stevel 15:02, 16 June 2010 (UTC)

Thanks for the fast clarification and direction!

Setting that finally worked on v1.16.0
Hello everyone,

It took me a while to get Shibboleth to work. I thought It would be nice to share what finally worked for me on MediaWiki v1.16.0

Undefined index: text in /w/skins/Vector.php on line 763
In the LdapAutoAuthentication module, a bug present that caused error.log to have many entries of the form "Undefined index: text in /w/skins/Vector.php on line 763". This was fixed in bug 85544 and can be corrected in this module by changing line 303 to unset( $personal_urls['logout'] );

= Problem with MW 1.18 =

With MW 1.18.x, I an error with the require statement. Replacing it with:

fixed the problem.

I'm still getting errors like this:

that I haven't yet figured out how to fix. Suggestions?

I've tried commenting out the 2 setupSession lines, and things seem to work for existing users, but I can't create new accounts as a MW administrator when logged in via Shibboleth. (My Wiki is set to disallow anonymous account creations.) ToddDTaft 18:07, 17 January 2012 (UTC)

Try  instead of.

Shibboleth plugin with MW 1.18
Mjirka (talk) 09:19, 28 March 2012 (UTC)
 * Edit extensions/ShibAuthPlugin.php and replace all ocurences of $user->setupSession with wfSetupSession
 * Set include path so that it contains path to mediawiki 'includes' directory. I put following lines into LocalSettings.php right before the shibboleth configuration:
 * Allow for empty paswords (also in LocalSettings.php):

= Is it possible for this extension to work if mod_fcgid is used to handle php =

I have this extension working well using the php5 module for Apache. I want to move to the worker MPM and mod_fcgid. Is it possible for this extension to work with mod_fcgid? When I try switching to mod_fcgid, shibboleth authentication is prompted for and works, but mediawiki does not recognize that the user is logged in.

SOLVED: For future reference, fcgid changes variables to REDIRECT_%. All I had to do was have $shib_UN reference REDIRECT_REMOTE_USER rather than REMOTE_USER.

= Forked extension on github =

Hi, I uploaded the source code to github, the latest version from here is in the 'official' branch. I made some bugfix and changes (per commits with explanations) in the 'master' branch, maybe some of you found it useful. You can fork it, send pull requests, create issues. We are using it with MW 1.19.x on PHP 5.4 now but we plan to upgrade to 1.20.x and upgrade the plugin as well if needed. -- Balazs Varga - 11:03 AM, April 14, 2013 (UTC)

= Debian MW 1.19 = A couple of quick points on enabling this great plugin on Debian 7. I eventually separated these from everything else here in the talk, but I was lost for a few days re-reading the talk and breaking other things along the way.

function ShibUpdateTheUser($existing, &$user) { global $shib_email; global $shib_RN; if (! $existing) { if($shib_email != null) $user->setEmail($shib_email); if($shib_RN != null) $user->setRealName($shib_RN); }    return true; } $shib_UN = ucfirst(strtolower($_SERVER['HTTP_EMAIL'])); --I.macdonald (talk) 03:07, 25 October 2013 (UTC)
 * Make sure to add the return true; shown below to the end of the ShibUpdateTheUser function. This is missing from the commented example in 1.2.4. Without error output enabled, you would see the "blank page" if you try to enable this without setting the return value expected.
 * Make sure to keep the ucfirst function on the shib_UN variable. I thought this was a formatting preference, and removed it on first pass. It is mentioned in the talk here, however without this you will get a duplicate user error.

= Return Page is Always Special:Badtitle =

I've set up a wiki in such a way that you must be logged in to view any page. Unfortunately, this appears to mess up the SSO login link on the "you need to log in" page; it always ends with ?target= https:// host.example.com/wiki/index.php?title=Special:Badtitle. I think that's because the Title that's used for the links on an error page is something nonsensical.

I solved the problem by just reusing whatever the current URL is, straight from PHP:

--- ShibAuthPlugin-orig.php	2014-03-04 15:45:52.022829036 -0500 +++ ShibAuthPlugin.php	2014-03-04 15:45:40.148827969 -0500 @@ -284,7 +284,7 @@ 		$shib_ConsumerPrefix = 'WAYF/'; else $shib_ConsumerPrefix = ''; -	$pageurl = $title->getLocalUrl; +	$pageurl = $_SERVER['REQUEST_URI']; if (! isset($shib_LoginHint)) $shib_LoginHint = "Login via Single Sign-on";

128.220.13.105 20:49, 4 March 2014 (UTC)

Thanks for this. Using the shib extension forked on github, this change seemed to work well. However, when a user logs out then the REQUEST_URI became the logout page, so when they clicked 'login' they got the logout page and a 'logout' link! If they then clicked on 'logout', they got taken to the login page. It got a bit confusing! :-) To correct this I added the following line (and comment) after yours:

--- ShibAuthPlugin.php.orig    2015-02-16 12:02:43.000000000 +0000 +++ ShibAuthPlugin.php 2015-02-26 15:17:57.643228436 +0000 @@ -296,7 +296,9 @@                 $shib_ConsumerPrefix = 'WAYF/'; else $shib_ConsumerPrefix = ''; -       $pageurl = $title->getLocalUrl; +       $pageurl = $_SERVER['REQUEST_URI']; +/*     If the user is at the logout page, then return them to the main page when they log in. */ +       $pageurl = preg_replace('/title=Special:UserLogout.*/', 'title=Main_Page', $pageurl); if (! isset($shib_LoginHint)) $shib_LoginHint = "Login via Single Sign-on";

This just replaces any attempt to return to the logout page with a return to the main page. (In our case this then prompts the user to login, and subsequently returns them back to the main page.)

--141.163.60.243 15:22, 26 February 2015 (UTC)

= Groups from Shibboleth Data =

Here's how to derive group membership from Shibboleth data.

// Set up a mapping from Shibboleth group names to MediaWiki group names. $shib_group_map = array(   'admin' => 'sysop',    'team5' => 'editor' ); // Get a list of MediaWiki groups to which the currently-authenticated // Shibboleth account should belong. Change "member" to the Shibboleth // attribute containing your group data. $shib_groups = array_filter(       array_map( function($g) { global $shib_group_map; if (array_key_exists($g, $shib_group_map)) { return $shib_group_map[$g]; }           },            preg_split('/;/', $_SERVER['member'])));

// Additions to the example ShibUpdateTheUser function. $wgHooks['ShibUpdateUser'][] = 'ShibUpdateTheUser'; function ShibUpdateTheUser($existing, &$user) { // Other global declarations. // ...   global $shib_group_map; global $shib_groups; // Other data updates. // ...   // Enforce Shibboleth group membership. foreach ($shib_group_map as $group) { if (in_array($group, $shib_groups)) { // Should be in the group... if (!in_array($group, $user->getGroups)) { // ...but isn't. Add them. $user->addGroup($group); }       } else { // Should not be in the group... if (in_array($group, $user->getGroups)) { // ...but is. Remove them. $user->removeGroup($group); }       }    }    return true; }

Note that this manages group membership completely. If there's a group in the $shib_group_map array, then the only way for a Shibboleth-authenticated person to be a member of that group is for the Shibboleth data to say so. If you add them manually in MediaWiki, this code will promptly remove them the next time they visit a page.

If you need to have groups that are sometimes derived from Shibboleth data and sometimes assigned by the wiki sysops, you'll need two groups with identical permissions, one group for each use case.

Asciiphil (talk) 18:30, 26 March 2014 (UTC)

Error with LoginForm::$mRemember
After shibboleth authentication users get a blank page and the logged error Cannot access protected property LoginForm::$mRemember in mediawiki-1.24.1/extensions/ShibAuthPlugin.php I had found this suggestion online in this howto --- a/includes/specials/SpecialUserlogin-orig.php +++ b/includes/specials/SpecialUserlogin.php @@ -77,7 +77,7 @@ class LoginForm extends SpecialPage { -      protected $mRemember; +      var $mRemember; But this change just moves the failure to PHP Fatal error: Call to a member function toString on a non-object in mediawiki-1.24.1/includes/User.php from includes/User.php public function saveSettings { ...                               'user_password' => $this->mPassword->toString,

It is caused by a change in MediaWiki 1.24 which introduced Password Hashing API, so passwords are now instances of the Password class with toString function, which is not available for simple strings. A possible workaround seems to be to remove the lines //For security, set password to a non-existant hash. if ($user->mPassword != "nologin"){ $user->mPassword = "nologin"; }

from the updateUser function in the Shibboleth extension.