Upgrade to 1.8 and preconfigure for Shibboleth 2.0

This commit is contained in:
Jérôme Schneider 2013-04-15 18:34:14 +02:00
parent 4ae55bea60
commit a9c0cbbffa
13 changed files with 268 additions and 151 deletions

10
README
View File

@ -2,8 +2,10 @@ saml_auth plugin allows you to use SAML 2.0 protocol with Elgg.
This plugin uses SimpleSAMLphp to "samlize" Elgg.
= Installation on Debian =
-> Install the fllowing packages : apache2, php5, simplesamlphp, memcached and php5-memcache
-> Configure a SAML 2.0 SP in simpleSAMLphp (follow simpleSAMLphp documentation)
-> Configure simpleSAMLphp to use memcache
-> Install this plugin into Elgg
- Install the fllowing packages : apache2, php5, memcached and php5-memcache
- Install SimpleSAMLphp into saml_auth/simplesamlphp directory
- Configure a SAML 2.0 SP in simpleSAMLphp (follow simpleSAMLphp documentation)
- Configure simpleSAMLphp to use memcache
- Install this plugin into Elgg

45
install_descartes.txt Normal file
View File

@ -0,0 +1,45 @@
= Installation sous Debian =
== Installation des paquets Debian ==
Le module saml auth dépend des paquets Debian memcached et php5-memcache.
Pour les installer il faut utilisr la commande suivante.
# apt-get install memcached php5-memcache
== Installer le module SAML Auth ==
Pour cela il suffit de copier le dossier saml_auth dans le dossier mod de votre Elgg.
== Configuration de SimpleSAMLphp ==
Le module Elgg utilise la bibliothèque SimpleSAMLphp pour se connecter à la fédération RENATER.
Cette bibliothéque est intégrée directement dans le module pour des raisons pratique.
Elle est installée dans saml_auth/simplesamlphp et son dossier de configuration est dans
saml_auth/simplesamlphp/config.
Le module saml_auth est pré-configuré pour utiliser le Shibboleth 2.0 RENATER de test.
Il faudra tout de même faire ajouter l'alias Apache suivant dans la configuration
du vhost de votre Elgg :
Alias /simplesamlphp CHEMIN_DE_VOTRE_ELGG/mod/saml_auth/simplesamlphp/www
Ensuite il faudra nous demander de rajouter votre "service provider" dans la fédération RENATER
de test ou le faire vous même en suivant les instructions :
https://services.renater.fr/federation/test/index
Pour mieux comprendre la configuration de SimpleSAMLphp en tant que sp :
http://simplesamlphp.org/docs/1.10/simplesamlphp-sp
== Activation du module ==
Il faut vous rendre dans l'administration de Elgg puis dans Plugins et choisir d'activer le plugin 'SAML Auth 0.1'.
== Configuration du module ==
Dans l'administration de ELgg vous pouvez modifier le plugin qui est
pour le moment configurer pour utiliser le Shibboleth de test de la fédération RENATER et
qui permet l'authentification classique ou bien par Shibboleth.

View File

@ -17,7 +17,9 @@
'saml_auth:settings:label:firstname' => "Firstname",
'saml_auth:settings:label:surname' => "Surname",
'saml_auth:settings:label:email' => "Email address",
'saml_auth:account:authentication:text' => "Please click on the Log In button.",
'saml_auth:settings:label:classical_auth' => "Enable classical authentification",
'saml_auth:account:authentication:text' => "Please click on the button to connect with UnivCloud",
'saml_auth:account:authentication:button' => "Log In with UnivCloud",
'saml_auth:samlerror' => "The SAML plugin is misconfigured. It will not be used.",
);

View File

@ -17,7 +17,9 @@
'saml_auth:settings:label:firstname' => "Prénom",
'saml_auth:settings:label:surname' => "Nom",
'saml_auth:settings:label:email' => "Courriel",
'saml_auth:account:authentication:text' => "Veuillez cliquer sur le bouton Connexion",
'saml_auth:settings:label:classical_auth' => "Autoriser l'auhtentification classique",
'saml_auth:account:authentication:text' => "Cliquer sur le bouton pour vous connecter via UnivCloud",
'saml_auth:account:authentication:button' => "Se connecter avec UnivCloud",
'saml_auth:samlerror' => "Le plugin SAML n'est pas configuré correctement. Il n'est pas utilisé.",
);

View File

@ -4,7 +4,7 @@
<field key="version" value="0.1" />
<field key="description" value="Provides SAML authentication" />
<field key="website" value="http://www.entrouvert.org/" />
<field key="copyright" value="(C) Entr'ouvert 2010" />
<field key="copyright" value="(C) Entr'ouvert 2012" />
<field key="licence" value="GNU Public License version 2 or later" />
<field key="elgg_version" value="2009022701" />
</plugin_manifest>

View File

@ -1,5 +1,4 @@
<?php
require_once('/usr/share/simplesamlphp/lib/_autoload.php');
/**
* Elgg SAML v2.0 authentication
*
@ -8,9 +7,10 @@
* @author Jerome Schneider <jschneider@entrouvert.com>
*/
require_once dirname(__FILE__) . '/simplesamlphp/lib/_autoload.php';
// Register the events
register_elgg_event_handler('init','system','saml_auth_init');
register_elgg_event_handler('logout','user','saml_logout');
elgg_register_event_handler('init','system','saml_auth_init');
/**
* SAML Authentication init
@ -22,20 +22,15 @@
global $CONFIG;
init_config();
$as = new SimpleSAML_Auth_Simple(get_plugin_setting('sp_name', 'saml_auth'));
$as = new SimpleSAML_Auth_Simple(elgg_get_plugin_setting('sp_name', 'saml_auth'));
$isAuth = $as->isAuthenticated();
$attributes = $as->getAttributes();
$elgg_user = saml_map_attributes($attributes);
if ($isAuth && ! isloggedin() && $elgg_user)
if ($isAuth && ! elgg_is_logged_in() && $elgg_user)
{
if ($user = get_entities_from_metadata('ldapDN', $elgg_user['ldapDN'], 'user')) {
$user = $user[0];
}
$user = get_user_by_username($elgg_user['username']);
if ($user) {
error_log('SAMLAuth found user "' . $user->username . '" for ldapDN "' . $elgg_user['ldapDN'] . '"');
} else {
error_log('SAMLAuth found no user for ldapDN ' . $elgg_user['ldapDN']);
trigger_error('SAMLAuth found user "' . $user->username, E_USER_NOTICE);
}
if (! $user)
{
@ -48,7 +43,6 @@
return true;
}
$user = get_user_by_username($elgg_user['username']);
$user->ldapDN = $elgg_user['ldapDN'];
}
if ($user) {
saml_sync_user($user, $elgg_user);
@ -58,55 +52,34 @@
}
// XXX: else return an error ?
}
if (! $isAuth && isloggedin() && $_SESSION['saml_user']) {
if (! $isAuth && elgg_is_logged_in() && $_SESSION['saml_user']) {
// unlogged from simplesamlphp but not from elgg
return logout();
}
elgg_register_event_handler('logout','user','saml_logout');
}
function init_config()
{
$config = find_plugin_settings('saml_auth');
$config = elgg_get_calling_plugin_entity('saml_auth');
if (! $config->sp_name)
set_plugin_setting('sp_name', 'default-sp', 'saml_auth');
elgg_set_plugin_setting('sp_name', 'default-sp', 'saml_auth');
if (! $config->username)
set_plugin_setting('username', 'uid', 'saml_auth');
elgg_set_plugin_setting('username', 'urn:oid:0.9.2342.19200300.100.1.1', 'saml_auth');
if (! $config->firstname)
set_plugin_setting('firstname', 'givenName', 'saml_auth');
elgg_set_plugin_setting('firstname', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.2', 'saml_auth');
if (! $config->surname)
set_plugin_setting('surname', 'sn', 'saml_auth');
elgg_set_plugin_setting('surname', 'urn:oid:2.5.4.4', 'saml_auth');
if (! $config->email)
set_plugin_setting('email', 'mail', 'saml_auth');
elgg_set_plugin_setting('email', 'urn:oid:0.9.2342.19200300.100.1.3', 'saml_auth');
if (! $config->classical_auth)
elgg_set_plugin_setting('classical_auth', 'yes', 'saml_auth');
}
function saml_sync_user($user, $elgg_user)
{
$user->name = $elgg_user['name'];
$user->email = $elgg_user['email'];
$user->ldapDN = $elgg_user['ldapDN'];
$bday = strptime($elgg_user['birthday'], '%d/%m/%Y');
if ($bday != FALSE) {
$user->birthday = mktime(0,0,0,
$bday['tm_mday'],
$bday['tm_mon'],
$bday['tm_year']);
}
$user->ircem = $elgg_user['ircem'];
$user->urssaf = $elgg_user['urssaf'];
$user->address = $elgg_user['address'];
$user->zipcode = $elgg_user['zipcode'];
$user->city = $elgg_user['city'];
$user->location = array($user->city, 'France');
$user->mobile = $elgg_user['mobile'];
$user->landline = $elgg_user['landline'];
remove_entity_relationships($user->guid, 'user2usertype');
foreach ($elgg_user['usertype'] as $usertype) {
$usertype = get_entities_by_title($usertype, 'object', 'usertype');
$usertype = $usertype[0];
if (!check_entity_relationship($user->guid, 'user2usertype', $usertype->guid)) {
add_entity_relationship($user->guid, 'user2usertype', $usertype->guid);
}
}
$user->save();
}
@ -130,15 +103,12 @@
{
$elgg_user = array();
$config = find_plugin_settings('saml_auth');
$config = elgg_get_calling_plugin_entity('saml_auth');
if (! $attributes[$config->username] or ! $attributes[$config->email])
return false;
$elgg_user['username'] = $attributes[$config->username][0];
$elgg_user['password'] = gen_rand_pwd();
$elgg_user['name'] = '';
if ($attributes['dn']) {
$elgg_user['ldapDN'] = $attributes['dn'][0];
}
if ($attributes[$config->surname] || $attributes[$config->firstname])
{
if ($attributes[$config->firstname])
@ -153,25 +123,17 @@
else
$elgg_user['name'] = $elgg_user['username'];
$elgg_user['email'] = $attributes[$config->email][0];
$elgg_user['usertype'] = $attributes['userClass'];
$elgg_user['ircem'] = $attributes['numeroIRCEM'][0];
$elgg_user['urssaf'] = $attributes['numeroURSSAF'][0];
$elgg_user['birthday'] = $attributes['dateOfBirth'][0];
$elgg_user['address'] = $attributes['homeStreetAddress'][0];
$elgg_user['zipcode'] = $attributes['homePostalCode'][0];
$elgg_user['city'] = $attributes['homeLocalityName'][0];
$elgg_user['mobile'] = $attributes['mobile'][0];
$elgg_user['landline'] = $attributes['telephoneNumber'][0];
return $elgg_user;
}
function saml_logout()
function saml_logout($page)
{
$as = new SimpleSAML_Auth_Simple(get_plugin_setting('sp_name', 'saml_auth'));
if ($as->isAuthenticated())
$as->logout();
global $CONFIG;
return true;
$auth = new SimpleSAML_Auth_Simple(elgg_get_plugin_setting('sp_name', 'saml_auth'));
if ($auth->isAuthenticated()) {
$auth->logout(elgg_get_site_url());
}
}

View File

@ -1,38 +0,0 @@
<?php
/**
* Elgg login form
*
* @package Elgg
* @subpackage Core
* @author Curverider Ltd
* @link http://elgg.org/
*/
global $CONFIG;
$form_body = "<p class=\"loginbox\"><label>" . elgg_echo('username') . "<br />" . elgg_view('input/text', array('internalname' => 'username', 'class' => 'login-textarea')) . "</label>";
$form_body .= "<br />";
$form_body .= "<label>" . elgg_echo('password') . "<br />" . elgg_view('input/password', array('internalname' => 'password', 'class' => 'login-textarea')) . "</label><br />";
$form_body .= elgg_view('login/extend');
$form_body .= elgg_view('input/submit', array('value' => elgg_echo('login'))) . " <div id=\"persistent_login\"><label><input type=\"checkbox\" name=\"persistent\" value=\"true\" />".elgg_echo('user:persistent')."</label></div></p>";
$form_body .= "<p class=\"loginbox\">";
$form_body .= (!isset($CONFIG->disable_registration) || !($CONFIG->disable_registration)) ? "<a href=\"{$vars['url']}pg/register/\">" . elgg_echo('register') . "</a> | " : "";
$form_body .= "<a href=\"{$vars['url']}account/forgotten_password.php\">" . elgg_echo('user:password:lost') . "</a></p>";
$login_url = $vars['url'];
if ((isset($CONFIG->https_login)) && ($CONFIG->https_login)) {
$login_url = str_replace("http", "https", $vars['url']);
}
?>
<div id="login-box">
<h2><?php echo elgg_echo('login'); ?></h2>
<?php
echo elgg_view('input/form', array('body' => $form_body, 'action' => "{$login_url}action/login"));
?>
</div>
<script type="text/javascript">
$(document).ready(function() { $('input[name=username]').focus(); });
</script>

View File

@ -1,44 +0,0 @@
<?php
/**
* Elgg SAML v2.0 authentication
*
* @package ElggSAMLAuth
* @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
* @author Jerome Schneider <jschneider@entrouvert.com>
*/
require_once('/usr/share/simplesamlphp/lib/_autoload.php');
$SAML = true;
try {
$as = new SimpleSAML_Auth_Simple(get_plugin_setting('sp_name', 'saml_auth'));
} catch (Exception $e) {
$SAML = false;
register_error(elgg_echo('saml_auth:samlerror'));
}
if (array_key_exists('login', $_REQUEST))
{
try {
$as->requireAuth();
} catch (Exception $e) {
$SAML = false;
register_error(elgg_echo('saml_auth:samlerror'));
}
}
$isAuth = $as->isAuthenticated();
?>
<?php if ($SAML == true): ?>
<div id="login-box">
<h2><?php echo elgg_echo('login'); ?></h2>
<form method="post" action="/">
<?php echo '<p>' . elgg_echo('saml_auth:account:authentication:text') . '</p>' ?>
<input type="hidden" value="1" name="login">
<input type="submit" value="<? echo elgg_echo('login') ?>" class="submit_button" name="">
</form>
</div>
<?php else: ?>
<?php echo elgg_view("account/forms/default_login"); ?>
<?php endif; ?>

View File

@ -0,0 +1,52 @@
<?php
/**
* Elgg login box
*
* @package Elgg
* @subpackage Core
*
* @uses $vars['module'] The module name. Default: aside
*/
$SAML = true;
try {
$as = new SimpleSAML_Auth_Simple(elgg_get_plugin_setting('sp_name', 'saml_auth'));
} catch (Exception $e) {
$SAML = false;
register_error(elgg_echo('saml_auth:samlerror'));
}
if (array_key_exists('login', $_REQUEST))
{
try {
$as->requireAuth();
} catch (Exception $e) {
$SAML = false;
register_error(elgg_echo('saml_auth:samlerror'));
}
}
$isAuth = $as->isAuthenticated();
$module = elgg_extract('module', $vars, 'aside');
$title = elgg_echo('login');
$login_url = elgg_get_site_url();
if (elgg_get_config('https_login')) {
$login_url = str_replace("http:", "https:", $login_url);
}
$body = "";
if ($SAML == true)
{
$body .= elgg_view_form('login_saml', array('action' => "{$login_url}"));
$body .= '<br />';
}
if (($SAML == false) or (elgg_get_plugin_setting('classical_auth', 'saml_auth') == 'yes'))
{
$body .= elgg_view_form('login', array('action' => "{$login_url}action/login"));
}
echo elgg_view_module($module, $title, $body);

View File

@ -0,0 +1,56 @@
<?php
/**
* Elgg drop-down login form
*/
$SAML = true;
try {
$as = new SimpleSAML_Auth_Simple(elgg_get_plugin_setting('sp_name', 'saml_auth'));
} catch (Exception $e) {
$SAML = false;
register_error(elgg_echo('saml_auth:samlerror'));
}
if (array_key_exists('login', $_REQUEST))
{
try {
$as->requireAuth();
} catch (Exception $e) {
$SAML = false;
register_error(elgg_echo('saml_auth:samlerror'));
}
}
$isAuth = $as->isAuthenticated();
if (elgg_is_logged_in()) {
return true;
}
$login_url = elgg_get_site_url();
if (elgg_get_config('https_login')) {
$login_url = str_replace("http:", "https:", elgg_get_site_url());
}
$body = "";
if ($SAML == true)
{
$body .= elgg_view_form('login_saml', array('action' => "{$login_url}"));
$body .= '<br />';
}
if (($SAML == false) or (elgg_get_plugin_setting('classical_auth', 'saml_auth') == 'yes'))
{
$body .= elgg_view_form('login', array('action' => "{$login_url}action/login"), array('returntoreferer' => TRUE));
}
?>
<div id="login-dropdown">
<?php
echo elgg_view('output/url', array(
'href' => 'login#login-dropdown-box',
'rel' => 'popup',
'class' => 'elgg-button elgg-button-dropdown',
'text' => elgg_echo('login'),
));
echo elgg_view_module('dropdown', '', $body, array('id' => 'login-dropdown-box'));
?>
</div>

View File

@ -0,0 +1,49 @@
<?php
/**
* Elgg login form
*
* @package Elgg
* @subpackage Core
*/
?>
<div>
<label><?php echo elgg_echo('loginusername'); ?></label>
<?php echo elgg_view('input/text', array(
'name' => 'username',
'class' => 'elgg-autofocus',
));
?>
</div>
<div>
<label><?php echo elgg_echo('password'); ?></label>
<?php echo elgg_view('input/password', array('name' => 'password')); ?>
</div>
<?php echo elgg_view('login/extend', $vars); ?>
<div class="elgg-foot">
<label class="mtm float-alt">
<input type="checkbox" name="persistent" value="true" />
<?php echo elgg_echo('user:persistent'); ?>
</label>
<?php echo elgg_view('input/submit', array('value' => elgg_echo('login'))); ?>
<?php
if (isset($vars['returntoreferer'])) {
echo elgg_view('input/hidden', array('name' => 'returntoreferer', 'value' => 'true'));
}
?>
<ul class="elgg-menu elgg-menu-general mtm">
<?php
if (elgg_get_config('allow_registration')) {
echo '<li><a class="registration_link" href="' . elgg_get_site_url() . 'register">' . elgg_echo('register') . '</a></li>';
}
?>
<li><a class="forgot_link" href="<?php echo elgg_get_site_url(); ?>forgotpassword">
<?php echo elgg_echo('user:password:lost'); ?>
</a></li>
</ul>
</div>

View File

@ -0,0 +1,16 @@
<?php
/**
* Elgg SAML v2.0 authentication
*
* @package ElggSAMLAuth
* @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
* @author Jerome Schneider <jschneider@entrouvert.com>
*/
?>
<div id="login-box">
<p><?php echo elgg_echo('saml_auth:account:authentication:text') ?></p>
<input type="hidden" value="1" name="login">
<input type="submit" value="<? echo elgg_echo('saml_auth:account:authentication:button') ?>" class="submit_button" name="">
</div>

View File

@ -6,7 +6,19 @@
* @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
* @author Jerome Schneider <jschnneider@entrouvert.com>
*/
$classical_auth_saml_string = elgg_echo('saml_auth:settings:label:classical_auth');
$classical_auth_saml_view = elgg_view('input/dropdown', array(
'name' => 'params[classical_auth]',
'options_values' => array(
'yes' => elgg_echo('option:yes'),
'no' => elgg_echo('option:no'),
),
'value' => $vars['entity']->classical_auth ? $vars['entity']->classical_auth : 'yes',
));
?>
<p>
<fieldset style="border: 1px solid; padding: 15px; margin: 0 10px 0 10px">
<legend><?php echo elgg_echo('saml_auth:settings:label:simplesamlphp');?></legend>
@ -14,6 +26,7 @@
<label for="params[sp_name]"><?php echo elgg_echo('saml_auth:settings:label:sp_name');?></label><br/>
<div class="example"><?php echo elgg_echo('saml_auth:settings:help:sp_name');?></div>
<input type="text" name="params[sp_name]" value="<?php echo $vars['entity']->sp_name;?>"/><br/>
<label><?php print $classical_auth_saml_string; ?></label> <?php print $classical_auth_saml_view ?>
</fieldset>
<fieldset style="border: 1px solid; padding: 15px; margin: 0 10px 0 10px">
<legend><?php echo elgg_echo('saml_auth:settings:label:attributes');?></legend>