Extension talk:SAMLAuth

From mediawiki.org
Latest comment: 9 years ago by Joseph.messerschmidt in topic Set RelayState value

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 ...

  1. Could my SP be sp.example.com ?
  2. If not, what it could be?
  3. 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)Reply

Support for MediaWiki 1.23+[edit]

I 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+[edit]

In 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[edit]

I 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+[edit]

In 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[edit]

Attempting 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.

--Technomensch (talk) 20:31, 29 August 2013 (UTC)Reply

Enable SAML Integration on site with existing users?[edit]

Q: 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)Reply

Set RelayState value[edit]

Is 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.

Joseph.messerschmidt (talk) 23:55, 14 August 2014 (UTC)Reply