Skip to content

Commit

Permalink
Merged Shibboleth integrated WAYF service from 18_STABLE
Browse files Browse the repository at this point in the history
  • Loading branch information
exe-cutor committed Feb 1, 2008
1 parent 5c17bef commit eefd788
Show file tree
Hide file tree
Showing 3 changed files with 258 additions and 42 deletions.
53 changes: 35 additions & 18 deletions auth/shibboleth/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@ Changes:
- 07. 2007: Fixed a but that caused problems with uppercase usernames
- 10. 2007: Removed the requirement for email address, surname and given name
attributes on request of Markus Hagman
- 11. 2007: Integrated WAYF Service in Moodle

Moodle Configuration with Dual login
-------------------------------------------------------------------------------
1. Protect the directory moodle/auth/shibboleth/ with Shibboleth.
1. Protect the directory moodle/auth/shibboleth/index.php with Shibboleth.
The page index.php in that directory actually logs in a Shibboleth user.
For Apache you have to define a rule like the following in the Apache config:

--
<Location ~ "/auth/shibboleth">
<Location ~ "/auth/shibboleth/index.php">
AuthType shibboleth
ShibRequireSession On
require valid-user
Expand All @@ -46,7 +47,7 @@ Moodle Configuration with Dual login
Options' and click on the the 'Shibboleth' settings.

3. Fill in the fields of the form. The fields 'Username', 'First name',
'Surname', etc should contain the name of the environment variables of the
'Surname', etc. should contain the name of the environment variables of the
Shibboleth attributes that you want to map onto the corresponding Moodle
variable (e.g. 'HTTP_SHIB_PERSON_SURNAME' for the person's last name, refer
the Shibboleth documentation or the documentation of your Shibboleth
Expand All @@ -56,20 +57,36 @@ Moodle Configuration with Dual login

#############################################################################
Shibboleth Attributes needed by Moodle:
For Moodle to work properly Shibboleth should at least provide the attributes
that are used as username, firstname, lastname and email in Moodle.
The attribute used for the username has to be unique for all Shibboleth user.
All attributes must obey a certain length, otherwise Moodle cuts off the
ends. Consult the Moodle documentation for further information on the maximum
lengths for each field in the user profile.
For Moodle to work properly Shibboleth should at least provide the attribute
that is used as usernam in Moodle. It has to be unique for all Shibboleth
users.
All attributes used for moodle must obey a certain length, otherwise Moodle
cuts off the ends. Consult the Moodle documentation for further information
on the maximum lengths for each field in the user profile.
#############################################################################

4. Save the changes for the 'Shibboleth settings'.

5.a If you want Shibboleth as your only authentication method, set the
'Alternate Login URL' in the 'Common settings' in
'Administrations >> Users >> Authentication Options' to the the URL of the
file 'moodle/auth/shibboleth/index.php'. This will enforce Shibboleth login.
5.a If you want Shibboleth as your only authentication method with an external
Where Are You From (WAYF) Service , set the 'Alternate Login URL' in the
'Common settings' in 'Administrations >> Users >> Authentication Options'
to the the URL of the file 'moodle/auth/shibboleth/index.php'.
This will enforce Shibboleth login.

5.b If you want to use the Moodle internal WAYF service, you have to activate it
in the Moodle Shibboleth authentication settings by checking the
'Moodle WAYF Service' checkbox and providing a list of entity IDs in the
'Identity Providers' textarea together with a name and an optional
SessionInitiator URL, which usually is an absolute or relative URL pointing
to the same host. If no SessionInitiator URL is given, the default one
'/Shibboleth.sso' will be used.
Also see https://spaces.internet2.edu/display/SHIB/SessionInitiator

Important Note: If you upgraded from a previous version of Moodle and now
want to use the integrated WAYF, you have to make sure that
in step 1 only the index.php script in
moodle/auth/shibboleth/ is protected but *not* the other
scripts and especially not the login.php script.

6.b If you want to use another authentication method together with Shibboleth,
in parallel, change the 'Instructions' in the 'Common settings' of the
Expand Down Expand Up @@ -110,11 +127,11 @@ authentication method unless they have two accounts in Moodle.

Shibboleth dual login with custom login page
--------------------------------------------------------------------------------
Of course you can create a dual login page that better fits your needs. For this
to work, you have to set up the two authentication methods (e.g. 'Manual' and
'Shibboleth') and specify an alternate login link to your own dual login page.
On that page you basically need a link to the Shibboleth-protected page
('/auth/shibboleth/index.php') for the Shibboleth login and a
You can create a dual login page that better fits your needs. For this
to work, you have to set up the two authentication methods (e.g. 'Manual
Accounts' and 'Shibboleth') and specify an alternate login link to your own dual
login page. On that page you basically need a link to the Shibboleth-protected
page ('/auth/shibboleth/index.php') for the Shibboleth login and a
form that sends 'username' and 'password' to moodle/login/index.php.
Consult the Moodle documentation for further instructions and requirements.

Expand Down
171 changes: 169 additions & 2 deletions auth/shibboleth/auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
* 2006-10-27 Upstream 1.7 changes merged in, added above credits from lib.php :-)
* 2007-03-09 Fixed authentication but may need some other changes
* 2007-10-03 Removed requirement for email address, surname and given name on request of Markus Hagman
* 2008-01-21 Added WAYF functionality
*/

if (!defined('MOODLE_INTERNAL')) {
Expand Down Expand Up @@ -113,8 +115,10 @@ function get_userinfo($username) {
return $result;
}

/*
/**
* Returns array containg attribute mappings between Moodle and Shibboleth.
*
* @return array
*/
function get_attributes() {
$configarray = (array) $this->config;
Expand Down Expand Up @@ -153,6 +157,10 @@ function can_change_password() {
return false;
}

/**
* Hook for login page
*
*/
function loginpage_hook() {
global $SESSION, $CFG;

Expand Down Expand Up @@ -193,21 +201,58 @@ function process_config($config) {
if (!isset ($config->convert_data)) {
$config->convert_data = '';
}

if (!isset($config->changepasswordurl)) {
$config->changepasswordurl = '';
}

if (!isset($config->login_name)) {
$config->login_name = 'Shibboleth Login';
}

// Clean idp list
if (isset($config->organization_selection) && !empty($config->organization_selection) && isset($config->alt_login) && $config->alt_login == 'on') {
$idp_list = get_idp_list($config->organization_selection);
if (count($idp_list) < 1){
return false;
}
$config->organization_selection = '';
foreach ($idp_list as $idp => $value){
$config->organization_selection .= $idp.', '.$value[0].', '.$value[1]."\n";
}
}


// save settings
set_config('user_attribute', $config->user_attribute, 'auth/shibboleth');

if (isset($config->organization_selection) && !empty($config->organization_selection)) {
set_config('organization_selection', $config->organization_selection, 'auth/shibboleth');
}
set_config('login_name', $config->login_name, 'auth/shibboleth');
set_config('convert_data', $config->convert_data, 'auth/shibboleth');
set_config('auth_instructions', $config->auth_instructions, 'auth/shibboleth');
set_config('changepasswordurl', $config->changepasswordurl, 'auth/shibboleth');


if (isset($config->alt_login) && $config->alt_login == 'on'){
set_config('alt_login', $config->alt_login, 'auth/shibboleth');
set_config('alternateloginurl', $CFG->wwwroot.'/auth/shibboleth/login.php');
} else {
set_config('alt_login', 'off', 'auth/shibboleth');
set_config('alternateloginurl', '');
$config->alt_login = 'off';
}

// Check values and return false if something is wrong
// Patch Anyware Technologies (14/05/07)
if (($config->convert_data != '')&&(!file_exists($config->convert_data) || !is_readable($config->convert_data))){
return false;
}

// Check if there is at least one entry in the IdP list
if (isset($config->organization_selection) && empty($config->organization_selection) && isset($config->alt_login) && $config->alt_login == 'on'){
return false;
}

return true;
}
Expand All @@ -225,4 +270,126 @@ function get_first_string($string) {
}
}


/**
* Sets the standard SAML domain cookie that is also used to preselect
* the right entry on the local wayf
*
* @param IdP identifiere
*/
function set_saml_cookie($selectedIDP) {
if (isset($_COOKIE['_saml_idp']))
{
$IDPArray = generate_cookie_array($_COOKIE['_saml_idp']);
}
else
{
$IDPArray = array();
}
$IDPArray = appendCookieValue($selectedIDP, $IDPArray);
setcookie ('_saml_idp', generate_cookie_value($IDPArray), time() + (100*24*3600));
}

/**
* Prints the option elements for the select element of the drop down list
*
*/
function print_idp_list(){
$config = get_config('auth/shibboleth');

$IdPs = get_idp_list($config->organization_selection);
if (isset($_COOKIE['_saml_idp'])){
$idp_cookie = generate_cookie_array($_COOKIE['_saml_idp']);
do {
$selectedIdP = array_pop($idp_cookie);
} while (!isset($IdPs[$selectedIdP]) && count($idp_cookie) > 0);

} else {
$selectedIdP = '-';
}

foreach($IdPs as $IdP => $data){
if ($IdP == $selectedIdP){
echo '<option value="'.$IdP.'" selected="selected">'.$data[0].'</option>';
} else {
echo '<option value="'.$IdP.'">'.$data[0].'</option>';
}
}
}


/**
* Generate array of IdPs from Moodle Shibboleth settings
*
* @param string Text containing tuble/triple of IdP entityId, name and (optionally) session initiator
* @return array Identifier of IdPs and their name/session initiator
*/

function get_idp_list($organization_selection) {
$idp_list = array();

$idp_raw_list = split("\n", $organization_selection);

foreach ($idp_raw_list as $idp_line){
$idp_data = split(',', $idp_line);
if (isset($idp_data[2]))
{
$idp_list[trim($idp_data[0])] = array(trim($idp_data[1]),trim($idp_data[2]));
}
elseif(isset($idp_data[1]))
{
$idp_list[trim($idp_data[0])] = array(trim($idp_data[1]));
}
}

return $idp_list;
}

/**
* Generates an array of IDPs using the cookie value
*
* @param string Value of SAML domain cookie
* @return array Identifiers of IdPs
*/
function generate_cookie_array($value) {

// Decodes and splits cookie value
$CookieArray = split(' ', $value);
$CookieArray = array_map('base64_decode', $CookieArray);

return $CookieArray;
}

/**
* Generate the value that is stored in the cookie using the list of IDPs
*
* @param array IdP identifiers
* @return string SAML domain cookie value
*/
function generate_cookie_value($CookieArray) {

// Merges cookie content and encodes it
$CookieArray = array_map('base64_encode', $CookieArray);
$value = implode(' ', $CookieArray);
return $value;
}

/**
* Append a value to the array of IDPs
*
* @param string IdP identifier
* @param array IdP identifiers
* @return array IdP identifiers with appended IdP
*/
function appendCookieValue($value, $CookieArray) {

array_push($CookieArray, $value);
$CookieArray = array_reverse($CookieArray);
$CookieArray = array_unique($CookieArray);
$CookieArray = array_reverse($CookieArray);

return $CookieArray;
}


?>
Loading

0 comments on commit eefd788

Please sign in to comment.