Extension:Shibboleth Authentication Plus

From MediaWiki.org
Jump to navigation Jump to search
MediaWiki extensions manual
OOjs UI icon advanced.svg
Shibboleth Authentication Plus
Release status: stable
Implementation User identity
Description Enriches the functionality of Shibboleth Authentication for group-based Authentication and Authorization. Also, implements a user notification messaging mechanism.
Author(s) GRNET & Atlantis Group (Univ. of Crete - EMAC)
Latest version 1.0 (2008-01-20)
MediaWiki 1.7+
License No license specified
Download Extension Page
GRNET & Atlantis Group (Univ. of Crete - EMAC), 2008
Translate the Shibboleth Authentication Plus extension if it is available at translatewiki.net
Check usage and version matrix.

Overview[edit]

This extension enriches the functionality of Shibboleth Authentication Extension by supporting group-based user authentication / authorization and by implementing a messaging mechanism for user notification during the authentication/authorization process. It is already in use in the Grnet Wikis MediaWiki Farm.


Current Version: 1.0

Installation Instructions[edit]

Compatibility[edit]

This extension is designed for MediaWiki 1.7 and latest versions. If you want to use this extension with the 1.6 version or previous ones, refer to bugs 5819 and 6006 and apply the SVN changes that occurred.

Shibboleth Environment Configuration[edit]

The extension requires that shibboleth environment has been configured and set up on the web server the wiki is hosted on. Once Shibboleth is running on the web server, make sure your configuration file is correctly set-up. Further assistance with the environment configuration can be provided by the administrator of the Shibboleth Service Provider (SP) that hosts your application. The extension uses lazy sessions in order to allow the standard wiki authentication to co-exist alongside with the Shibboleth authentication. Therefore, the relevant environment configuration should be made as described below. Full sessions are also acceptable for use.

You will require to indicate the extension which WAYF url to use. Following is the part of the SP configuration file (shibboleth.xml), where the WAYF url should be completed:

...
<Sessions lifetime="7200" timeout="3600" checkAddress="false" consistentAddress="true"
	handlerURL="/Shibboleth.sso" handlerSSL="false" idpHistory="true" idpHistoryDays="7">
	<SessionInitiator isDefault="true" id="example" Location="/WAYF/idp.example.org"
		Binding="urn:mace:shibboleth:sp:1.3:SessionInit"
		wayfURL="https://idp.example.org/PATH/TO/AUTH"
		wayfBinding="urn:mace:shibboleth:1.0:profiles:AuthnRequest"/

The part of the shibboleth configuration file that allows lazy sessions is described below: (False is for lazy sessions, true for mandatory sessions)

...
<Host name="host.example.org">
	<Path name="wikipath" authType="shibboleth" requireSession="false"/>

Following is the part of the Apache's Vhosts configuration file (vhosts.conf) that enables lazy sessions:

...
<Location /pathname>
        AuthType shibboleth
        Require shibboleth
</Location>

If you don't want lazy sessions but instead would rather require shibboleth authentication, then use:

...
<Location /pathname>
        AuthType shibboleth
        ShibRequireSession On
        Require valid-user
</Location>

Download the Extension[edit]

The code of this extension is composed of three parts. The extended code of the Shibboleth Authentication Extension, the code that implements the group-based user authentication/authorization and the code that implements the messaging mechanism. There is a detailed description of the Shibboleth Authentication Plus Extension code at the following sections.

Shibboleth Authentication Extension Code[edit]

Download the code of the Shibboleth Authentication Extension and place it in the extensions folder, in a file called ShibAuthPlugin.php. Go to the function AutoAuth, define the global variable $shib_GRP and replace the defined "if expression" with the following one:

if($user->isLoggedIn()){
                
  //map the list of shibboleth groups to the corresponding local user groups 
  if($shib_GRP != null){
     for ($i=0; $i<count($shib_GRP); $i++){
	$user->addGroup($shib_GRP[$i]);
     }
     BringBackAA();
     return;
  }
}

The only changes that have been made in the code of Shibboleth Authentication Extension are the definition of the $shib_GRP variable that contains the list of user groups, the mapping of that list to the local groups and the assignment of the user to the local groups.

Shibboleth Authentication Plus Extension Code[edit]

In this section you can see the code of the Shibboleth Authentication Plus Extension. The extension implements a mechanism for group-based user authentication and authorization. Authentication is based on eduPersonPrincipalName which provides a unique identifier of the user across the federation. The value of eduPersonPrincipalName is assigned to the variable $shib_UN (Shibboleth Authentication Extension variable). The authorization scheme is based on eduPersonOrgUnitDN and its constituent components. The value of eduPersonOrgUnitDN variable has the following format: ou=group1, ou=group2, o=domain, c=suffix (e.g ou=editor, o=university, c=com). The extension collects the groups of "your_domain" and maps them to the current list of the local groups (the locally defined groups should be a subset of all possible values the "ou"s in users' DN could get).Upon the completion of the mapping process of "ou" values to local groups, the group membership of the user is stored in the array variable $shib_GRP (Shibboleth Authentication Plus Extension variable). The user takes the authorization privileges of these groups. Place the code in the extensions folder, in a file called ShibAuthPlusPlugin.php and replace the "o=your_domain,c=your_suffix" expression with your own domain.

<?php
    /**
    * Version 1.0 (Works out of box with MW 1.7 or above)
    *
    * Extends the Shibboleth Authentication Plugin for group-based authentication and authorization. 
    * 
    * Copyright 2008, GRNET & Atlantis Group (Univ. of Crete - EMAC)
    *
    * Documentation at http://meta.wikimedia.org/wiki/Shibboleth_Authentication_Plus
    * 
    * Extension Maintainer:
    *         * GRNET & Atlantis Group (Univ. of Crete - EMAC) <www-support AT grnet DOT gr> 
    *           (Please drop me an e-mail if you'd like to help)
    * Extension Developers:
    *         * GRNET & Atlantis Group (Univ. of Crete - EMAC)
    */

     #Load ShibAuthPlugin
     require_once('ShibAuthPlugin.php');
     #Load ShibAuthPlusMessaging
     require_once('ShibAuthPlusMessaging.php');

     global $message;	
	
     //Take the shibboleth values of the attribute eduPersonOrgUnitDN
     $orgunidn = $_SERVER["HTTP_SHIB_EP_ORGUNITDN"];

     //Take the shibboleth values of the attribute eduPersonPrincipalName
     $principalname = $_SERVER["REMOTE_USER"];

     //The eduPersonOrgUnitDN has been sent
     if ($orgunidn!=""){
	$orgunidn = strtolower($orgunidn);
		
	//Split the attribute's basic domain's  values
	$table_groups =  explode(";",$orgunidn);

	//For each basic domain 
	for ($i=0; $i<count($table_groups); $i++){
   	   //If there is a domain that matches your_domain
	   $pos = strpos($table_groups[$i], "o=your_domain,c=your_suffix");	
	   if($pos!==false){
			
	     //Take the groups of "your_domain"
	     $your_group = $table_groups[$i];
	     $table_your_group =  explode(",",$your_group);
	
	     $index = 0;
		
	     //For each group of your_domain
	     for ($j=0; $j<count($table_your_group); $j++){
				
	        //Make the table of the groups of your_domain
	        $pos1 = strpos($table_your_group[$j], "ou"); 
	        if($pos1!==false){
		  $tmp_groups = explode("ou=",$table_your_group[$j]);
		  $groups[$index] = $tmp_groups[1];
		  $index++;		
	        }//if
            }//for
          }//if
        }//for

	//You are not member of your_domain
	if(count($groups)==0){
	    //The attribute eduPersonPrincipalName has been sent
	    if($principalname!=""){
		$message = "You are not a member of your_domain community. 
                            You can not be  authenticated/authorized.";
		$shib_UN = "";
	    }
	    else {
	      $message = "Your IdP hasn't sent your identity. Additionally, you are not a member 
                        of your_domain community. You have not been authenticated/authorized.";
	    }
        }
	else if(count($groups)>0){
	
	    //Take the current wiki idendity
	    $tmp1 = str_replace("_", "", $wgDBprefix);
		
	    //For all of the user's groups
	    for ($i=0; $i<count($groups); $i++){
		//The attribute eduPersonPrincipalName has been sent
		if ($principalname!=""){
		   $shib_UN= str_replace("@", "AT", $principalname);
		    $message = "You have been successfully authenticated and authorized!";
		}
		//The attribute eduPersonPrincipalName hasn't been sent
		else {
		    $shib_UN= $groups[$i];
		    $message = "Your IdP hasn't sent your identity. The authentication and 
                                    authorization process completed via your user group.";
		}
    	        //Fill the user's group extension variable 
		$shib_GRP = $groups;
                break;	
	     }//for
	}//else if
	
     }//if orgunitdn!=""
	
     //The attribute eduPersonOrgUnitDN hasn't been sent
     else if ($orgunitdn==""){
		
        //The attribute eduPersonPrincipalName has been sent
        if ($principalname!=""){
	   $shib_UN= "";
	   $message = "Your IdP hasn't sent your identity. You have not been authenticated/authorized."; 
	}
	//The attribute eduPersonOrgUnitDN hasn't been sent
	else {
	   $message = "Your IdP hasn't sent any of the necessary attributes.";
	}
     }
?>

In addition, the Shibboleth Authentication Plus Extension implements a messaging mechanism in order to inform the users during the process of his Authentication and Authorization. You can see the generated messages by simply adding the {{SHIBMESSAGE}} variable in your desirable wiki page. Place the code in the extensions folder, in a file called ShibAuthPlusMessaging.php.

<?php

   /**
    * Version 1.0 (Works out of box with MW 1.7 or above)
    *
    * Implements a messaging mechanism for Shibboleth Authentication Plus Extension for user notification 
    * during the authentication and authorization process. 
    * 
    * Copyright 2008, GRNET & Atlantis Group (Univ. of Crete - EMAC)
    *
    * Documentation at http://meta.wikimedia.org/wiki/Shibboleth_Authentication_Plus
    * 
    * Extension Maintainer:
    *         * GRNET & Atlantis Group (Univ. of Crete - EMAC) <www-support AT grnet DOT gr> 
    *           (Please drop me an e-mail if you'd like to help)
    * Extension Developers:
    *         * GRNET & Atlantis Group (Univ. of Crete - EMAC)
    */

    $wgCustomVariables = array('SHIBMESSAGE');
 
    $wgHooks['MagicWordMagicWords'][]          = 'wfAddCustomVariable';
    $wgHooks['MagicWordwgVariableIDs'][]       = 'wfAddCustomVariableID';
    $wgHooks['LanguageGetMagic'][]             = 'wfAddCustomVariableLang';
    $wgHooks['ParserGetVariableValueSwitch'][] = 'wfGetCustomVariable';

    function wfAddCustomVariable(&$magicWords) {
	 foreach($GLOBALS['wgCustomVariables'] as $var) $magicWords[] = "MAG_$var";
		 return true;
    }
													 
    function wfAddCustomVariableID(&$variables) {
      foreach($GLOBALS['wgCustomVariables'] as $var) $variables[] = constant("MAG_$var");
	return true;
    }
																  
    function wfAddCustomVariableLang(&$langMagic, $langCode = 100) {
      foreach($GLOBALS['wgCustomVariables'] as $var) {
        $magic = "MAG_$var";
        $langMagic[defined($magic) ? constant($magic) : $magic] = array(0,$var);
      }
      return true;
    }

    function wfGetCustomVariable(&$parser,&$cache,&$index,&$ret) {
      switch ($index) {
      case MAG_SHIBMESSAGE:
        $parser->disableCache();
        $ret = $GLOBALS['message'];
        break;
      }
      return true;
    }
?>

Shibboleth Authentication Plus Extension Configuration[edit]

Now it's time to configure and load the extension. To do that, just add the following lines to LocalSettings.php in the root of the mediawiki directory (most of the configuration instructions have been taken from the Shibboleth Authentication Extension page).

##Shibboleth Authentication Stuff
#Load ShibAuthPlusPlugin
require_once('extensions/ShibAuthPlusPlugin.php');

#Last portion of the shibboleth WAYF url for lazy sessions.
#This value is found in your shibboleth.xml file on the setup for your SP
#WAYF url will look something like: /Shibboleth.sso/WAYF/$shib_WAYF
$shib_WAYF = "idp.example.org";

#Is the assertion consumer service located at an https address (highly recommended)
# Default for compatibility with previous version: false
$shib_Https = true;

#Prompt for user to login
$shib_LoginHint = "Login via Single Sign-on";

# Where is the assertion consumer service located on the website?
# Default: "/Shibboleth.sso"
$shib_AssertionConsumerServiceURL = "/Shibboleth.sso";

#Do you want to map in names from Shibboleth data?
#Feel free to use extra PHP code to munge the variables if you'd like
#Additionally if you wish to only map some of the name data, set this to true
#and either blank shib_RN and shib_email or comment them out entirely.
$shib_map_info = "true";

#Ssssh.... quiet down errors
$olderror = error_reporting(E_ALL ^ E_NOTICE);

#Map Real Name to what Shibboleth variable(s)?
$shib_RN = ucfirst(strtolower($_SERVER['HTTP_FIRST_NAME'])) . ' '
	 . ucfirst(strtolower($_SERVER['HTTP_LAST_NAME']));

#Map e-mail to what Shibboleth variable?
$shib_email = $_SERVER['HTTP_EMAIL'];

#Shibboleth doesn't really support logging out very well.  To take care of
#this we simply get rid of the logout link when a user is logged in through
#Shib.  Alternatively, you can uncomment and set the variable below to a link
#that will either clear the user's cookies or log the user out of the Idp and
#instead of deleting the logout link, the extension will change it instead.
#$shib_logout = "http://example.org";

#Turn error reporting back on
error_reporting($olderror);

#Activate Shibboleth Plugin
SetupShibAuth();

#Define here the list of your local groups and the privileges of these groups 

#$wgGroupPermissions['test']['read']= true;
#$wgGroupPermissions['test']['edit']= true;
#$wgGroupPermissions['test']['createpage']= true;
#$wgGroupPermissions['test']['createtalk']= true;
#$wgGroupPermissions['test']['upload']= true;
#$wgGroupPermissions['test']['reupload']= true;
#$wgGroupPermissions['test']['minoredit']= true;
#$wgGroupPermissions['test']['delete']= true;
#$wgGroupPermissions['test']['move']= true;
#$wgGroupPermissions['test']['editinterface']= true;
#$wgGroupPermissions['test']['upload_by_url']= true;
#$wgGroupPermissions['test']['uploadlocal']= true;
#$wgGroupPermissions['test']['protect']= true;

One important point in the configuration process is the definition of the local groups list. That list has to map the list of the expected shibboleth groups. This is required for the correct operation of the Authorization process. If the extension does not map any of the shibboleth groups to any of the local groups, the user takes the privileges of an anonymous user.