From 217720e6549d77ad9febefb61325d97f9c1ae04b Mon Sep 17 00:00:00 2001 From: Gerbrand Sterrenburg Date: Tue, 30 Nov 2021 16:15:16 +0100 Subject: [PATCH 1/2] - fixed redirect issue - cleaned up code - refined login page code - added setting for text on login page --- .gitignore | 1 + Limesurvey-SAML-Authentication/AuthSAML.php | 139 +++++++++++++------- 2 files changed, 94 insertions(+), 46 deletions(-) diff --git a/.gitignore b/.gitignore index e43b0f9..3d72576 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .DS_Store +.idea \ No newline at end of file diff --git a/Limesurvey-SAML-Authentication/AuthSAML.php b/Limesurvey-SAML-Authentication/AuthSAML.php index 5ea8706..5adbccc 100644 --- a/Limesurvey-SAML-Authentication/AuthSAML.php +++ b/Limesurvey-SAML-Authentication/AuthSAML.php @@ -12,6 +12,8 @@ * URL: https://github.com/Frankniesten/Limesurvey-SAML-Authentication */ +use SimpleSAML\Auth\Simple; + class AuthSAML extends LimeSurvey\PluginManager\AuthPluginBase { protected $storage = 'DbStorage'; @@ -20,6 +22,9 @@ class AuthSAML extends LimeSurvey\PluginManager\AuthPluginBase static protected $description = 'Core: SAML authentication'; static protected $name = 'SAML'; + /** + * @var array + */ protected $settings = array( 'simplesamlphp_path' => array( 'type' => 'string', @@ -83,11 +88,14 @@ class AuthSAML extends LimeSurvey\PluginManager\AuthPluginBase ), ); - public function init() { + /** + * init + */ + public function init() + { $this->storage = $this->get('storage_base', null, null, 'DbStorage'); $this->subscribe('getGlobalBasePermissions'); - $this->subscribe('beforeLogin'); $this->subscribe('newUserSession'); $this->subscribe('afterLogout'); @@ -98,13 +106,13 @@ public function init() { } /** + * getGlobalBasePermissions + * * Add AuthLDAP Permission to global Permission */ public function getGlobalBasePermissions() { $this->getEvent()->append('globalBasePermissions', array( - - 'auth_saml' => array( 'create' => false, 'update' => false, @@ -118,43 +126,55 @@ public function getGlobalBasePermissions() )); } - public function beforeLogin() { - $ssp = $this->get_saml_instance(); - + /** + * beforeLogin + */ + public function beforeLogin() + { if ($this->get('force_saml_login', null, null, false)) { - $ssp->requireAuth(); + $this->getSAMLInstance()->requireAuth(); } - if ($ssp->isAuthenticated()) { + if ($this->getSAMLInstance()->isAuthenticated()) { $this->setAuthPlugin(); $this->newUserSession(); } } + /** + * afterLogout + */ public function afterLogout() { - $ssp = $this->get_saml_instance(); $redirect = $this->get('logout_redirect', null, null, '/admin'); - if ($ssp->isAuthenticated()) { - Yii::app()->controller->redirect($ssp->getLogoutUrl($redirect)); + + if ($this->getSAMLInstance()->isAuthenticated()) { + Yii::app()->controller->redirect($this->getSAMLInstance()->getLogoutUrl($redirect)); Yii::app()->end(); } } + /** + * newLoginForm + */ public function newLoginForm() { - $authtype_base = $this->get('authtype_base', null, null, 'Authdb'); - - $ssp = $this->get_saml_instance(); - $this->getEvent()->getContent($authtype_base)->addContent('
  • Click on that button to initiate SAML Login

  • ', 'prepend'); - } - - public function newUserSession() { + $authTypeBase = $this->get('authtype_base', null, null, 'Authdb'); - $ssp = $this->get_saml_instance(); + $loginFormContent = '
    Click on that button to initiate SAML Login

    '; - if ($ssp->isAuthenticated()) { + $this + ->getEvent() + ->getContent($authTypeBase) + ->addContent($loginFormContent, 'prepend'); + } + /** + * newUserSession + */ + public function newUserSession() + { + if ($this->getSAMLInstance()->isAuthenticated()) { $sUser = $this->getUserName(); $name = $this->getUserCommonName(); $mail = $this->getUserMail(); @@ -189,12 +209,18 @@ public function newUserSession() { } elseif (is_null($oUser)) { throw new CHttpException(401, gT("We are sorry but you do not have an account.")); } else { - // *** Update user *** $auto_update_users = $this->get('auto_update_users', null, null, true); if ($auto_update_users) { + /** + * Added 'users_name' => $sUser + * to prevent getting stuck in redirect loop when + * there is a difference in case between existing username + * and the username coming from SAML + */ $changes = array ( + 'users_name' => $sUser, 'full_name' => $name, 'email' => $mail, ); @@ -207,6 +233,7 @@ public function newUserSession() { } } $flag = $this->get('simplesamlphp_cookie_session_storage', null, null, true); + if ($flag){ $session = SimpleSAML_Session::getSessionFromRequest(); $session->cleanup(); @@ -214,33 +241,35 @@ public function newUserSession() { } /** + * getSAMLInstance + * * Initialize SAML authentication - * @return void + * @return Simple */ - public function get_saml_instance() { - + public function getSAMLInstance() + { if ($this->ssp == null) { + $simpleSAMLPath = $this->get('simplesamlphp_path', null, null, '/var/www/simplesamlphp'); + require_once($simpleSAMLPath.'/lib/_autoload.php'); - $simplesamlphp_path = $this->get('simplesamlphp_path', null, null, '/var/www/simplesamlphp'); - - require_once($simplesamlphp_path.'/lib/_autoload.php'); - - $saml_authsource = $this->get('saml_authsource', null, null, 'limesurvey'); - - $this->ssp = new \SimpleSAML\Auth\Simple($saml_authsource); + $samlAuthSource = $this->get('saml_authsource', null, null, 'limesurvey'); + $this->ssp = new Simple($samlAuthSource); } return $this->ssp; } /** + * getUserName + * * Get Userdata from SAML Attributes * @return void */ - public function getUserName() { - + public function getUserName() + { if ($this->_username == null) { $username = $this->getUserNameAttribute(); + if ($username !== false) { $this->setUsername($username); } @@ -249,27 +278,39 @@ public function getUserName() { return $this->_username; } + /** + * getUserNameAttribute + * + * @return false + */ public function getUserNameAttribute() { - $ssp = $this->get_saml_instance(); - $attributes = $this->ssp->getAttributes(); + $attributes = $this->getSAMLInstance()->getAttributes(); + if (!empty($attributes)) { $saml_uid_mapping = $this->get('saml_uid_mapping', null, null, 'uid'); + if (array_key_exists($saml_uid_mapping, $attributes) && !empty($attributes[$saml_uid_mapping])) { - $username = $attributes[$saml_uid_mapping][0]; - return $username; + return $attributes[$saml_uid_mapping][0]; } } + return false; } - public function getUserCommonName() { - + /** + * getUserCommonName + * + * @return string + */ + public function getUserCommonName() + { $name = ''; - $ssp = $this->get_saml_instance(); - $attributes = $this->ssp->getAttributes(); + $attributes = $this->getSAMLInstance()->getAttributes(); + if (!empty($attributes)) { $saml_name_mapping = $this->get('saml_name_mapping', null, null, 'cn'); + if (array_key_exists($saml_name_mapping , $attributes) && !empty($attributes[$saml_name_mapping])) { $name = $attributes[$saml_name_mapping][0]; } @@ -278,13 +319,19 @@ public function getUserCommonName() { return $name; } - public function getUserMail() { - + /** + * getUserMail + * + * @return string + */ + public function getUserMail() + { $mail = ''; - $ssp = $this->get_saml_instance(); - $attributes = $this->ssp->getAttributes(); + $attributes = $this->getSAMLInstance()->getAttributes(); + if (!empty($attributes)) { $saml_mail_mapping = $this->get('saml_mail_mapping', null, null, 'mail'); + if (array_key_exists($saml_mail_mapping , $attributes) && !empty($attributes[$saml_mail_mapping])) { $mail = $attributes[$saml_mail_mapping][0]; } From ac2a347fee3a0c2b62967646ae484465c401128f Mon Sep 17 00:00:00 2001 From: Gerbrand Sterrenburg Date: Tue, 30 Nov 2021 17:00:31 +0100 Subject: [PATCH 2/2] updated README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dd9f9c1..570e93c 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ LimeSurvey authentication plugin for authenticating users against an SAML Identi - Paste it inside **limesurvey/plugins/AuthSAML** folder - Configure the plugin from the **Plugin Manager** - Go to **Admin > Configuration > Plugin Manager** or **https:/example.com/index.php/admin/pluginmanager/sa/index** and **Enable** the plugin -- Place your own custom **saml_logo.gif** image at **imesurvey/assets/images**. It will be displayed as the login button +- Place your own custom **saml_logo.png** image at **imesurvey/assets/images**. It will be displayed as the login button ## Configuration options - **Path to the SimpleSAMLphp folder**: path to the simpleSAMLphp installation @@ -24,6 +24,7 @@ set this to **true** so the code can handle session conficts between simpleSAMLp - **SAML attributed used as name**: the attribute returned from the IdP that will be the users human friendly name - **Auto create users**: check if the user exists in the local database and if not the plugin creates the user from the SAML metadata - **Auto update users**: check if IdP has different attribute values for email and name and update them on LimeSurvey +- **SAML login Text**: Text show on the Login page - **Force SAML login**: if this is set to true the plugin will force the login path to use only simpleSAMLphp - **Authtype base**: LimeSurvey internal configuration options, use it only if you know what you are doing. Configures where the users data are stored. - **Storage base**: LimeSurvey internal configuration options, use it only if you know what you are doing. Configures where the plugin settings are stored.