From eefd788bdc6e1d95855c9c1eff9bfcf20505d301 Mon Sep 17 00:00:00 2001 From: exe-cutor Date: Fri, 1 Feb 2008 12:45:24 +0000 Subject: [PATCH] Merged Shibboleth integrated WAYF service from 18_STABLE --- auth/shibboleth/README.txt | 53 +++++++---- auth/shibboleth/auth.php | 171 +++++++++++++++++++++++++++++++++++- auth/shibboleth/config.html | 76 +++++++++++----- 3 files changed, 258 insertions(+), 42 deletions(-) diff --git a/auth/shibboleth/README.txt b/auth/shibboleth/README.txt index 815bc6919a..2c88215367 100644 --- a/auth/shibboleth/README.txt +++ b/auth/shibboleth/README.txt @@ -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: -- - + AuthType shibboleth ShibRequireSession On require valid-user @@ -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 @@ -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 @@ -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. diff --git a/auth/shibboleth/auth.php b/auth/shibboleth/auth.php index fab06b7d99..05c69a2b31 100644 --- a/auth/shibboleth/auth.php +++ b/auth/shibboleth/auth.php @@ -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')) { @@ -113,8 +115,10 @@ class auth_plugin_shibboleth extends auth_plugin_base { return $result; } - /* + /** * Returns array containg attribute mappings between Moodle and Shibboleth. + * + * @return array */ function get_attributes() { $configarray = (array) $this->config; @@ -153,6 +157,10 @@ class auth_plugin_shibboleth extends auth_plugin_base { return false; } + /** + * Hook for login page + * + */ function loginpage_hook() { global $SESSION, $CFG; @@ -193,21 +201,58 @@ class auth_plugin_shibboleth extends auth_plugin_base { 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; } @@ -225,4 +270,126 @@ class auth_plugin_shibboleth extends auth_plugin_base { } } + + /** + * 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 ''; + } else { + echo ''; + } + } + } + + + /** + * 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; + } + + ?> diff --git a/auth/shibboleth/config.html b/auth/shibboleth/config.html index 073666b757..115327599f 100755 --- a/auth/shibboleth/config.html +++ b/auth/shibboleth/config.html @@ -27,45 +27,75 @@ - - - : + Moodle WAYF Service: - - alt_login) and $config->alt_login == 'on' ){ + echo 'checked="checked"'; + } + ?> /> + + If you check this, Moodle will use its own WAYF service instead of the one configured for Shibboleth. Moodle will display a drop-down list on this alternative login page where the user has to select his Identity Provider. + - if ($config->convert_data and $config->convert_data != '' and !is_readable($config->convert_data)) { + + Identity Providers: + + + organization_selection) && empty($config->organization_selection) && isset($config->alt_login) && $config->alt_login == 'on') { echo '
'; - print_string("auth_shib_convert_data_warning", "auth"); + print_string("auth_shib_no_organizations_warning", "auth"); echo ''; } - - ?> + ?> - + Provide a list of Identity Provider entityIDs to let the user choose from on the login page. +On each line there must be a comma-separated tuple for entityID of the IdP (see the Shibboleth metadata file) and Name of IdP as it shall be displayed in the drow-down list. +As an optional third parameter you can add the location of a Shibboleth session initiator that shall be used in case your Moodle installation is part of a multi federation setup. + + Authentication Method Name: + + + + Provide a name for the Shibboleth authentication method that is familiar to your users. This could be the name of your Shibboleth federation, e.g. "SWITCHaai Login" or "InCommon Login" and so on. + : @@ -82,6 +112,8 @@ instructions + + ', true, false); -- 2.39.5