/** * Hook on the logout action to make sure we can logout on SimpleSAML * * @param string $hook the name of the hook * @param string $type the type of the hook * @param bool $return_value current return value * @param array $params supplied params * * @return void */ public static function action($hook, $type, $return_value, $params) { global $SIMPLESAML_SOURCE; $login_source = simplesaml_get_from_session('saml_login_source'); if (!isset($login_source)) { return; } // store session data because session is destroyed $SIMPLESAML_SOURCE = $login_source; // after session is destroyed forward to saml logout elgg_register_plugin_hook_handler('forward', 'system', '\\ColdTrick\\SimpleSAML\\Logout::forward'); }
/** * Take some actions during the login event of a user * * @param string $event the name of the event * @param string $type type of the event * @param ElggUser $object the current user trying to login * * @return void */ public static function loginEvent($event, $type, $object) { if (!$object instanceof \ElggUser) { return; } $saml_attributes = simplesaml_get_from_session('saml_attributes'); $source = simplesaml_get_from_session('saml_source'); // simplesaml login? if (!isset($saml_attributes) || !isset($source)) { return; } // source enabled if (!simplesaml_is_enabled_source($source)) { return; } // validate additional authentication rules if (!simplesaml_validate_authentication_attributes($source, $saml_attributes)) { return; } // link the user to this source $saml_uid = elgg_extract('elgg:external_id', $saml_attributes); if (!empty($saml_uid)) { if (is_array($saml_uid)) { $saml_uid = $saml_uid[0]; } // save the external id so the next login will go faster simplesaml_link_user($object, $source, $saml_uid); } // save the attributes to the user simplesaml_save_authentication_attributes($object, $source, $saml_attributes); // save source name for single logout simplesaml_store_in_session('saml_login_source', $source); // cleanup simplesaml_remove_from_session('saml_attributes'); simplesaml_remove_from_session('saml_source'); }
} simplesaml_link_user($user, $source, $saml_uid); } // save attributes simplesaml_save_authentication_attributes($user, $source, $saml_attributes); // restore hidden setting access_show_hidden_entities($hidden); // notify user about registration system_message(elgg_echo('registerok', [elgg_get_site_entity()->name])); // cleanup session simplesaml_remove_from_session('saml_source'); simplesaml_remove_from_session('saml_attributes'); // try to login the user try { // check for the persistent login plugin setting $persistent = false; if (elgg_get_plugin_setting($source . '_remember_me', 'simplesaml')) { $persistent = true; } // login the user login($user); // get forward url $forward_url = simplesaml_get_from_session('last_forward_from', ''); simplesaml_remove_from_session('last_forward_from'); } catch (Exception $e) { // make sure we don't force login simplesaml_store_in_session('simplesaml_disable_sso', true); $forward_url = ''; } } forward($forward_url);
register_error(elgg_echo('simplesaml:error:no_source')); forward($forward_url); } $label = simplesaml_get_source_label($source); if (!simplesaml_is_enabled_source($source)) { register_error(elgg_echo('simplesaml:error:source_not_enabled', [$label])); forward($forward_url); } try { $saml_auth = new SimpleSAML_Auth_Simple($source); } catch (Exception $e) { register_error(elgg_echo('simplesaml:error:class', [$e->getMessage()])); forward($forward_url); } // make sure we can forward you to the correct url $last_forward = simplesaml_get_from_session('last_forward_from'); if (!isset($last_forward)) { simplesaml_store_in_session('last_forward_from', $_SERVER['REFERER']); } // login with SAML if (!$saml_auth->isAuthenticated()) { // not logged in on IDP, so do that $saml_auth->login(); } // user is authenticated with IDP, so link in Elgg $saml_attributes = simplesaml_get_authentication_attributes($saml_auth, $source); if (empty($saml_attributes)) { register_error(elgg_echo('simplesaml:authorize:error:attributes', [$label])); forward($forward_url); } // check for additional authentication rules
/** * This function checks if authentication needs to be forces over an authentication source. * * @return void */ function simplesaml_check_force_authentication() { if (elgg_is_logged_in()) { // no need to do anything if already logged in return; } if (isset($_GET['disable_sso'])) { // bypass for sso simplesaml_store_in_session('simplesaml_disable_sso', true); return; } $disable_sso = simplesaml_get_from_session('simplesaml_disable_sso', false); if ($disable_sso === true) { // sso was bypassed on a previous page return; } if (strpos(current_page_url(), elgg_normalize_url('saml/no_linked_account')) === 0) { // do not force authentication on the no_linked_account page return; } // get the plugin setting that defines force authentications $setting = elgg_get_plugin_setting('force_authentication', 'simplesaml'); if (empty($setting)) { return; } // check if the authentication source is enabled if (!simplesaml_is_enabled_source($setting)) { return; } // make sure we can forward you to the correct url $last_forward = simplesaml_get_from_session('last_forward_from'); if (!isset($last_forward)) { simplesaml_store_in_session('last_forward_from', current_page_url()); } forward("saml/login/{$setting}"); }
<?php $source = elgg_extract('saml_source', $vars); $label = simplesaml_get_source_label($source); $saml_attributes = simplesaml_get_from_session('saml_attributes'); echo elgg_format_element('div', ['class' => 'mbm'], elgg_echo('simplesaml:forms:register:description', [$label])); // check for missing fields // we need name and email if (!elgg_extract('elgg:firstname', $saml_attributes) && !elgg_extract('elgg:lastname', $saml_attributes)) { // no name fields, so ask $label = elgg_format_element('label', ['for' => 'displayname'], elgg_echo('name')); $input = elgg_view('input/text', ['name' => 'displayname', 'id' => 'displayname']); echo elgg_format_element('div', [], $label . $input); } if (!elgg_extract('elgg:email', $saml_attributes)) { // no email field, so ask $label = elgg_format_element('label', ['for' => 'email'], elgg_echo('email')); $input = elgg_view('input/email', ['name' => 'email', 'id' => 'email']); echo elgg_format_element('div', [], $label . $input); } $footer = elgg_view('input/hidden', ['name' => 'saml_source', 'value' => $source]); $footer .= elgg_view('input/submit', ['value' => elgg_echo('register')]); echo elgg_format_element('div', ['class' => 'elgg-foot'], $footer);
* the option to link or create an account */ $source = get_input('saml_source'); if (elgg_is_logged_in()) { register_error(elgg_echo('simplesaml:error:loggedin')); forward(); } if (empty($source)) { register_error(elgg_echo('simplesaml:error:no_source')); forward(); } $label = simplesaml_get_source_label($source); if (!simplesaml_is_enabled_source($source)) { register_error(elgg_echo('simplesaml:error:source_not_enabled', [$label])); forward(); } $session_source = simplesaml_get_from_session('saml_source'); if ($session_source !== $source) { register_error(elgg_echo('simplesaml:error:source_mismatch')); forward(); } // cleanup login form simplesaml_unextend_login_form(); $allow_registration = simplesaml_allow_registration($source); // prepare page elements $title_text = elgg_echo('simplesaml:no_linked_account:title', [$label]); $content = elgg_view('simplesaml/no_linked_account', ['saml_source' => $source, 'allow_registration' => $allow_registration]); // build body $body = elgg_view_layout('one_column', ['title' => $title_text, 'content' => $content]); // draw page echo elgg_view_page($title_text, $body);