Extension talk:SAMLAuth
In the statement below...
You must install, and configure SimpleSAMLphp as a SAML 2.0 Service Provider on the same domain as the Media Wiki instance.
What exactly do you mean by "same domain"?
Supposing that my domain is www.example.com ...
- Could my SP be sp.example.com ?
- If not, what it could be?
- If I had to have something like www.example.com/sp could I employ mod_rewrite and tell Apache to redirect to sp.example.com ?
Thanks a lot :)
Richard Gomes 03:13, 3 January 2011 (UTC)
- Should work. Check http://en.wikipedia.org/wiki/Security_Assertion_Markup_Language 134.91.30.112 11:44, 18 June 2012 (UTC)
Support for MediaWiki 1.23+
editI believe that this extension is not compatible with MediaWiki 1.23 and newer and needs quite some change to continue working. The problem is that some member variables of the LoginForm class are now protected (see source code), but this extensions relies on accessing them.
Support for MediaWiki 1.21+
editIn some version between MediaWiki 1.19 and 1.22, some of the interfaces changed. This patch makes it work for my MediaWiki 1.22.2 installation:
diff -pur old/SpecialSAMLAuth/SpecialSAMLAuth_body.php new/SpecialSAMLAuth/SpecialSAMLAuth_body.php --- old/SpecialSAMLAuth/SpecialSAMLAuth_body.php 2014-07-05 22:46:34.586010262 +0200 +++ new/SpecialSAMLAuth/SpecialSAMLAuth_body.php 2014-07-05 23:20:47.594030235 +0200 @@ -25,7 +25,6 @@ class SAMLAuth extends SpecialPage { function __construct() { parent::__construct( 'SAMLAuth' ); - wfLoadExtensionMessages('SAMLAuth'); } /* @@ -279,7 +278,7 @@ class SAMLAuthLogin extends AuthPlugin { return false; } - function addUser( $user, $password ) { + function addUser( $user, $password, $email = '', $realname = '' ) { return false; }
Save it as $IP/extensions/SpecialSAMLAuth.patch
and execute the following command in $IP/extensions/
:
patch -p1 < SpecialSAMLAuth.patch
Support for user groups
editI am just thinking whether it would be a big effort to add support for user groups. I will use this page to brainstorm a bit. Maybe I have time to implement it at some point...
The idea would be to read the groups from a configurable SAML attribute when the user logs in. We would then compare the list of values with the actual groups that the user has (which we get with getGroups from the user class), add the missing (with addGroup) and remove the superflous ones (with removeGroup).
Update: Here's the first version of the patch:
diff -pur orig/SpecialSAMLAuth/SpecialSAMLAuth_body.php patch/SpecialSAMLAuth/SpecialSAMLAuth_body.php --- orig/SpecialSAMLAuth/SpecialSAMLAuth_body.php 2013-06-09 20:02:41.000000000 +0200 +++ patch/SpecialSAMLAuth/SpecialSAMLAuth_body.php 2013-11-14 22:08:24.038276603 +0100 @@ -34,9 +34,9 @@ class SAMLAuth extends SpecialPage { */ function execute( $par ) { global $wgRequest, $wgOut, $wgUser, $IP, $wgAuth, $wgContLang, $wgSessionName, $wgSessionName, $wgCookiePrefix; - global $wgSAMLAuthSimpleSAMLphpLibPath, $wgSAMLAuthSimpleSAMLphpConfigPath, $wgSAMLAuthSimpleSAMLphpentity, $wgSAMLAuthUserNameAttr, $wgSAMLAuthRealNameAttr, $wgSAMLAuthEmailAttr; + global $wgSAMLAuthSimpleSAMLphpLibPath, $wgSAMLAuthSimpleSAMLphpConfigPath, $wgSAMLAuthSimpleSAMLphpentity, $wgSAMLAuthUserNameAttr, $wgSAMLAuthRealNameAttr, $wgSAMLAuthEmailAttr, $wgSAMLAuthGroupsAttr; global $wgSAMLCreateUser, $wgSAMLVerifyIdP; - global $simplesaml_RN, $simplesaml_email; + global $simplesaml_RN, $simplesaml_email, $simplesaml_groups; global $wgSamlAuthDebug; // save all the session settings to recreate later - after SimpleSAMLphp @@ -74,6 +74,7 @@ class SAMLAuth extends SpecialPage { $wgSamlAuthDebug && error_log('attributes: ' . var_export($attributes, true)); $simplesaml_RN = $attributes[$wgSAMLAuthRealNameAttr][0]; $simplesaml_email = $attributes[$wgSAMLAuthEmailAttr][0]; + $simplesaml_groups = $attributes[$wgSAMLAuthGroupsAttr]; // convert all to lower case $simplesaml_UN = $wgContLang->lc($attributes[$wgSAMLAuthUserNameAttr][0]); @@ -147,9 +148,20 @@ class SAMLAuth extends SpecialPage { if($simplesaml_RN != null) { $user->setRealName($simplesaml_RN); } + if($simplesaml_groups != null) { + $wgSamlAuthDebug && error_log('MediaWiki + SAML: Removing old groups: ' . implode(', ', $user->getGroups())); + foreach($user->getGroups() as $group) { + $user->removeGroup($group); + } + $wgSamlAuthDebug && error_log('MediaWiki + SAML: Adding new groups: ' . implode(', ', $simplesaml_groups)); + foreach($simplesaml_groups as $group) { + $user->addGroup($group); + } + } $wgUser->saveSettings(); wfSetupSession(); $wgSamlAuthDebug && error_log('Debug simpleSAMLphp + MediaWiki: USER-IDENTIFIED [' . $simplesaml_UN . ']'); + $wgSamlAuthDebug && error_log('Mediawiki groups: ' . implode(', ', $user->getGroups())); $wgUser->setCookies(); } else if ($wgSAMLCreateUser) { @@ -203,7 +215,18 @@ class SAMLAuth extends SpecialPage { if( $wgEmailAuthentication && User::isValidEmailAddr( $user->getEmail() ) ) { $user->sendConfirmationMail(); } - + + if($simplesaml_groups != null) { + $wgSamlAuthDebug && error_log('MediaWiki + SAML: Removing old groups: ' . implode(', ', $user->getGroups())); + foreach($user->getGroups() as $group) { + $user->removeGroup($group); + } + $wgSamlAuthDebug && error_log('MediaWiki + SAML: Adding new groups: ' . implode(', ', $simplesaml_groups)); + foreach($simplesaml_groups as $group) { + $user->addGroup($group); + } + } + //Finish it off $user->setToken(); $user->saveSettings(); @@ -283,7 +306,17 @@ class SAMLAuthLogin extends AuthPlugin { $user->setEmail($simplesaml_email); if($simplesaml_RN != null) $user->setRealName($simplesaml_RN); - + if($simplesaml_groups != null) { + $wgSamlAuthDebug && error_log('MediaWiki + SAML: Removing old groups: ' . implode(', ', $user->getGroups())); + foreach($user->getGroups() as $group) { + $user->removeGroup($group); + } + $wgSamlAuthDebug && error_log('MediaWiki + SAML: Adding new groups: ' . implode(', ', $simplesaml_groups)); + foreach($simplesaml_groups as $group) { + $user->addGroup($group); + } + } + //$user->setPassword('somepassword'); return true; } diff -pur orig/SpecialSAMLAuth/SpecialSAMLAuth.php patch/SpecialSAMLAuth/SpecialSAMLAuth.php --- orig/SpecialSAMLAuth/SpecialSAMLAuth.php 2010-10-27 21:54:07.000000000 +0200 +++ patch/SpecialSAMLAuth/SpecialSAMLAuth.php 2013-11-14 22:12:10.278528515 +0100 @@ -51,7 +51,7 @@ $wgHooks['MediaWikiPerformAction'][] = ' // Configuration of SAMLAuth extension -global $wgSAMLAuthSimpleSAMLphpLibPath, $wgSAMLAuthSimpleSAMLphpConfigPath, $wgSAMLAuthSimpleSAMLphpentity, $wgSAMLAuthUserNameAttr, $wgSAMLAuthRealNameAttr, $wgSAMLAuthEmailAttr, $wgSamlAuthDebug, $wgSAMLVerifyIdP, $wgSAMLCreateUser; +global $wgSAMLAuthSimpleSAMLphpLibPath, $wgSAMLAuthSimpleSAMLphpConfigPath, $wgSAMLAuthSimpleSAMLphpentity, $wgSAMLAuthUserNameAttr, $wgSAMLAuthRealNameAttr, $wgSAMLAuthEmailAttr, $wgSAMLAuthGroupsAttr, $wgSamlAuthDebug, $wgSAMLVerifyIdP, $wgSAMLCreateUser; //$wgSAMLAuthSimpleSAMLphpLibPath = '/usr/local/mw-test/simplesamlphp-1.5'; // Library path for SimpleSAMLphp $wgSAMLAuthSimpleSAMLphpLibPath = '/home/piers/git/public/simplesamlphp'; // Library path for SimpleSAMLphp //$wgSAMLAuthSimpleSAMLphpConfigPath = '/usr/local/mw-test/simplesamlphp-1.5/config'; // config.php path for SimpleSAMLphp @@ -60,6 +60,7 @@ $wgSAMLAuthSimpleSAMLphpentity = 'defaul $wgSAMLAuthUserNameAttr = 'eduPersonPrincipalName'; // User name attribute $wgSAMLAuthRealNameAttr = 'cn'; // Real Name attribute $wgSAMLAuthEmailAttr = 'mail'; // email address attribute +//$wgSAMLAuthGroupsAttr = 'groups'; // User groups attribute // verify if user's IdP is known in the user settings? $wgSAMLVerifyIdP = false;
Save it as $IP/extensions/SpecialSAMLAuth.patch
and execute the following command in $IP/extensions/
:
patch -p1 < SpecialSAMLAuth.patch
Support for MediaWiki 1.18+
editIn MediaWiki 1.18, the internal user handling has changed, so SAMLAuth 0.3 doesn't work with MediaWiki 1.18 and above. The same issue concerns other authentification modules (for example HttpAuth and Shibboleth Authentication). The following patch is a workaround for the problem:
diff -pur old/SpecialSAMLAuth/SpecialSAMLAuth_body.php new/SpecialSAMLAuth/SpecialSAMLAuth_body.php --- old/SpecialSAMLAuth/SpecialSAMLAuth_body.php 2013-06-09 15:55:50.000000000 +0200 +++ new/SpecialSAMLAuth/SpecialSAMLAuth_body.php 2013-06-09 15:54:39.000000000 +0200 @@ -114,7 +114,7 @@ class SAMLAuth extends SpecialPage { $token = LoginForm::getLoginToken(); $params = new FauxRequest(array( 'wpName' => $simplesaml_UN, - 'wpPassword' => '', + 'wpPassword' => 'a', 'wpDomain' => '', 'wpRemember' => '', 'wpLoginToken' => $token, @@ -148,7 +148,7 @@ class SAMLAuth extends SpecialPage { $user->setRealName($simplesaml_RN); } $wgUser->saveSettings(); - $wgUser->setupSession(); + wfSetupSession(); $wgSamlAuthDebug && error_log('Debug simpleSAMLphp + MediaWiki: USER-IDENTIFIED [' . $simplesaml_UN . ']'); $wgUser->setCookies(); } @@ -176,9 +176,18 @@ class SAMLAuth extends SpecialPage { $loginForm = new LoginForm($params); $result = $loginForm->authenticateUserData(); + /* For security, scramble the password to ensure the user can + * only login through simpleSAMLphp. This set the password to a 15 byte + * random string. + */ + $pass = null; + for($i = 0; $i < 15; ++$i) + $pass .= chr(mt_rand(0,255)); + $loginForm->mPassword = $pass; + //Now we _do_ the black magic $loginForm->mRemember = false; - $loginForm->initUser(&$user, TRUE); + $loginForm->initUser($user, TRUE); // set the user values $user->setOption('SAMLAuth_IdentityProvider', $idp); @@ -188,14 +197,6 @@ class SAMLAuth extends SpecialPage { if($simplesaml_RN != null) { $user->setRealName($simplesaml_RN); } - /* For security, scramble the password to ensure the user can - * only login through simpleSAMLphp. This set the password to a 15 byte - * random string. - */ - $pass = null; - for($i = 0; $i < 15; ++$i) - $pass .= chr(mt_rand(0,255)); - $user->setPassword($pass); // email confirmation loop global $wgEmailAuthentication; @@ -206,7 +207,7 @@ class SAMLAuth extends SpecialPage { //Finish it off $user->setToken(); $user->saveSettings(); - $user->setupSession(); + wfSetupSession(); $user->setCookies(); $wgUser = $user; $user->addNewUserLogEntry();
Save it as $IP/extensions/SpecialSAMLAuth.patch
and execute the following command in $IP/extensions/
:
patch -p1 < SpecialSAMLAuth.patch
Strict Standards: Declaration should be compatible with that of AuthPlugin
editAttempting to install on MW 1.21.1.
Receiving the following error:
Strict Standards: Declaration of SAMLAuthLogin::addUser() should be compatible with that of AuthPlugin::addUser() in C:\inetpub\sites\<sitename>\wiki\extensions\SpecialSAMLAuth\SpecialSAMLAuth_body.php on line 296
I noticed that on the AuthPlugin documentation, it states that the LocalSettings.php requires:
require_once( "$IP/extensions/MyAuthPlugin/MyAuthPlugin.php" ); $wgAuth = new MyAuthPlugin();
not just
require_once( "\$IP/extensions/SpecialSAMLAuth/SpecialSAMLAuth.php" );
Using this information, I updated my LocalSettings.php accordingly.
Now the following error has moved from line 296 to 245
Strict Standards: Declaration of SAMLAuthLogin::addUser() should be compatible with that of AuthPlugin::addUser() in C:\inetpub\sites\<sitename>\wiki\extensions\SpecialSAMLAuth\SpecialSAMLAuth_body.php on line 245
It also breaks the Error Logging/Troubleshooting tools and will no longer load my Profile.
Any assistance would be greatly appreciated. Thank you in advance.
Enable SAML Integration on site with existing users?
editQ: I have a wiki that has a few hundred users. I am migrating to a new server (easy) but I want to enable SAML. The user IDs will collide. What is the cleanest way to migrate and enable SAML retroactively without losing contributions by users (e.g. bbob now logs in with SAML based login and still is bbob the same user he was for the laster year)? 148.177.1.217 18:25, 4 October 2013 (UTC)
Set RelayState value
editIs it possible to set the RelayState token to the current page title/URL? I would like to redirect users back to the page they were on after they log in. The default MediaWiki login handles this, but SAML requires the RelayState token.