From 4d83cb804e9a5371745a8c6a7f0069d2e86b7126 Mon Sep 17 00:00:00 2001 From: Olav Morken <olav.morken@uninett.no> Date: Thu, 27 Mar 2008 15:33:34 +0000 Subject: [PATCH] Added support for Auth MemCookie. git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@451 44740490-163a-0410-bde0-09ae8108e29a --- config-templates/authmemcookie.php | 69 ++++++++++++++ config-templates/config.php | 3 +- dictionaries/errors.php | 7 ++ extra/auth_memcookie.conf | 38 ++++++++ lib/SimpleSAML/AuthMemCookie.php | 146 +++++++++++++++++++++++++++++ www/authmemcookie.php | 105 +++++++++++++++++++++ 6 files changed, 367 insertions(+), 1 deletion(-) create mode 100644 config-templates/authmemcookie.php create mode 100644 extra/auth_memcookie.conf create mode 100644 lib/SimpleSAML/AuthMemCookie.php create mode 100644 www/authmemcookie.php diff --git a/config-templates/authmemcookie.php b/config-templates/authmemcookie.php new file mode 100644 index 000000000..fa3e4a9de --- /dev/null +++ b/config-templates/authmemcookie.php @@ -0,0 +1,69 @@ +<?php + +/** + * This is the configuration file for the Auth MemCookie example. + */ + +$config = array( + + /* + * This is the name of the cookie we should save the session id in. The value of this option must match the + * Auth_memCookie_CookieName option in the Auth MemCookie configuration. The default value is 'AuthMemCookie'. + * + * Default: + * 'cookiename' => 'AuthMemCookie', + */ + 'cookiename' => 'AuthMemCookie', + + /* + * This option specifies the name of the attribute which contains the username of the user. It must be set to + * a valid attribute name. + * + * Examples: + * 'username' => 'uid', // LDAP attribute for user id. + * 'username' => 'mail', // LDAP attribute for email address. + * + * Default: + * No default value. + */ + 'username' => NULL, + + /* + * This option specifies the name of the attribute which contains the groups of the user. Set this option to + * NULL if you don't want to include any groups. + * + * Example: + * 'groups' => 'edupersonaffiliation', + * + * Default: + * 'groups' => NULL, + */ + 'groups' => NULL, + + /* + * This option contains the hostname of IP address of the memcache server where we should store the + * authentication information. Thos option should match the address part of the + * Auth_memCookie_Memcached_AddrPort option in the Auth MemCookie configuration. + * + * Examples: + * 'memcache.host' => '192.168.93.52', + * 'memcache.host' => 'memcache.example.org', + * + * Default: + * 'memcache.host' => '127.0.0.1', + */ + 'memcache.host' => '127.0.0.1', + + /* + * This option contains the port number of the memcache server where we should store the + * authentication information. Thos option should match the port part of the + * Auth_memCookie_Memcached_AddrPort option in the Auth MemCookie configuration. + * + * Default: + * 'memcache.port' => 11211, + */ + 'memcache.port' => 11211, + +); + +?> \ No newline at end of file diff --git a/config-templates/config.php b/config-templates/config.php index 6b67ad173..53901fba8 100644 --- a/config-templates/config.php +++ b/config-templates/config.php @@ -98,7 +98,8 @@ $config = array ( 'enable.shib13-sp' => false, 'enable.shib13-idp' => false, 'enable.openid-provider'=> false, - + 'enable.authmemcookie' => false, + /* * This value is the duration of the session in seconds. Make sure that the time duration of * cookies both at the SP and the IdP exceeds this duration. diff --git a/dictionaries/errors.php b/dictionaries/errors.php index 18c61d9a6..eed068e44 100644 --- a/dictionaries/errors.php +++ b/dictionaries/errors.php @@ -337,4 +337,11 @@ $lang = array( 'de' => 'Fehler bei der Kommunikation mit dem CAS Server.', ), + 'title_CONFIG' => array( + 'en' => 'Configuration error', + ), + 'descr_CONFIG' => array( + 'en' => 'simpleSAMLphp appears to be misconfigured.', + ), + ); \ No newline at end of file diff --git a/extra/auth_memcookie.conf b/extra/auth_memcookie.conf new file mode 100644 index 000000000..77e5e12a0 --- /dev/null +++ b/extra/auth_memcookie.conf @@ -0,0 +1,38 @@ +<Location /> + # This is a list of memcache servers which Auth MemCookie + # should use. It is a ','-separated list of + # host:port-pairs. + # Note that this list must list the same servers as the + # 'authmemcookie.servers'-option in config.php in the + # configuration for simpleSAMLphp. + Auth_memCookie_Memcached_AddrPort "127.0.0.1:11211" + + # This must be set to 'on' to enable Auth MemCookie for + # this directory. + Auth_memCookie_Authoritative on + + # This adjusts the maximum number of data elements in the + # session data. The default is 10, which can be to low. + Auth_memCookie_SessionTableSize "40" + + # These two commands are required to enable access control + # in Apache. + AuthType Cookie + AuthName "My Login" + + # This command causes apache to redirect to the given + # URL when we receive a '401 Authorization Required' + # error. We redirect to "/openssophp/spSSOInit.php", + # which initializes a login to the IdP. + ErrorDocument 401 "/simplesaml/authmemcookie.php" + +</Location> + +<Location /secret> + # This allows all authenticated users to access the + # directory. To learn more about the 'Require' command, + # please look at: + # http://httpd.apache.org/docs/2.0/mod/core.html#require + Require valid-user +</Location> + diff --git a/lib/SimpleSAML/AuthMemCookie.php b/lib/SimpleSAML/AuthMemCookie.php new file mode 100644 index 000000000..a316041d9 --- /dev/null +++ b/lib/SimpleSAML/AuthMemCookie.php @@ -0,0 +1,146 @@ +<?php + +/** + * This is a helper class for the Auth MemCookie module. + * It handles the configuration, and implements the logout handler. + * + * @author Olav Morken, UNINETT AS. + * @package simpleSAMLphp + * @version $Id$ + */ +class SimpleSAML_AuthMemCookie { + + /** + * This is the singleton instance of this class. + */ + private static $instance = NULL; + + + /** + * The configuration for Auth MemCookie. + */ + private $amcConfig; + + /** + * This function is used to retrieve the singleton instance of this class. + * + * @return The singleton instance of this class. + */ + public static function getInstance() { + if(self::$instance === NULL) { + self::$instance = new SimpleSAML_AuthMemCookie(); + } + + return self::$instance; + } + + + /** + * This function implements the constructor for this class. It loads the Auth MemCookie configuration. + */ + private function __construct() { + /* Load Auth MemCookie configuration. */ + $globalConfig = SimpleSAML_Configuration::getInstance(); + SimpleSAML_Configuration::init($GLOBALS['configdir'], 'authmemcookie', 'authmemcookie.php'); + $this->amcConfig = SimpleSAML_Configuration::getInstance('authmemcookie'); + } + + + /** + * This function retrieves the name of the cookie from the configuration. + * + * @return The name of the cookie. + */ + public function getCookieName() { + $cookieName = $this->amcConfig->getValue('cookiename', 'AuthMemCookie'); + if(!is_string($cookieName) || strlen($cookieName) === 0) { + throw new Exception('Configuration option \'cookiename\' contains an invalid value. This option should be a string.'); + } + + return $cookieName; + } + + + /** + * This function retrieves the name of the attribute which contains the username from the configuration. + * + * @return The name of the attribute which contains the username. + */ + public function getUsernameAttr() { + $usernameAttr = $this->amcConfig->getValue('username'); + if($usernameAttr === NULL) { + throw new Exception('Missing required configuration option \'username\' in authmemcookie.php.'); + } + + return $usernameAttr; + } + + + /** + * This function retrieves the name of the attribute which contains the groups from the configuration. + * + * @return The name of the attribute which contains the groups. + */ + public function getGroupsAttr() { + $groupsAttr = $this->amcConfig->getValue('groups'); + + return $groupsAttr; + } + + + /** + * This function creates and initializes a Memcache object from our configuration. + * + * @return A Memcache object initialized from our configuration. + */ + public function getMemcache() { + + $memcacheHost = $this->amcConfig->getValue('memcache.host', '127.0.0.1'); + if(!is_string($memcacheHost)) { + throw new Exception('Invalid value of the \'memcache.host\' configuration option. This option' . + ' should be a string with a hostname or a string with an IP address.'); + } + + $memcachePort = $this->amcConfig->getValue('memcache.port', 11211); + if(!is_int($memcachePort)) { + throw new Exception('Invalid value of the \'memcache.port\' configuration option. This option' . + ' should be an integer.'); + } + + $memcache = new Memcache; + $memcache->connect($memcacheHost, $memcachePort); + + return $memcache; + } + + + /** + * This function logs the user out by deleting the session information from memcache. + */ + private function doLogout() { + + $cookieName = $this->getCookieName(); + + /* Check if we have a valid cookie. */ + if(!array_key_exists($cookieName, $_COOKIE)) { + return; + } + + $sessionID = $_COOKIE[$cookieName]; + + /* Delete the session from memcache. */ + + $memcache = $this->getMemcache(); + $memcache->delete($sessionID); + } + + + /** + * This function implements the logout handler. It deletes the information from Memcache. + */ + public static function logoutHandler() { + self::getInstance()->doLogout(); + } +} + +?> \ No newline at end of file diff --git a/www/authmemcookie.php b/www/authmemcookie.php new file mode 100644 index 000000000..d76274b57 --- /dev/null +++ b/www/authmemcookie.php @@ -0,0 +1,105 @@ +<?php + +/** + * This file implements an script which can be used to authenticate users with Auth MemCookie. + * See: http://authmemcookie.sourceforge.net/ + * + * The configuration for this script is stored in config/authmemcookie.php. + * + * The file extra/auth_memcookie.conf contains an example of how Auth Memcookie can be configured + * to use simpleSAMLphp. + */ + +require_once('_include.php'); + +require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/Utilities.php'); +require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/Session.php'); +require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/AuthMemCookie.php'); + +try { + /* Load simpleSAMLphp configuration. */ + $globalConfig = SimpleSAML_Configuration::getInstance(); + $session = SimpleSAML_Session::getInstance(TRUE); + + /* Check if this module is enabled. */ + if(!$globalConfig->getValue('enable.authmemcookie', FALSE)) { + SimpleSAML_Utilities::fatalError($session->getTrackID(), 'NOACCESS'); + } + + /* Load Auth MemCookie configuration. */ + $amc = SimpleSAML_AuthMemCookie::getInstance(); + + /* Check if the user is authorized. We attempt to authenticate the user if not. */ + if (!$session->isValid('saml2') ) { + SimpleSAML_Utilities::redirect( + '/' . $globalConfig->getBaseURL() . 'saml2/sp/initSSO.php', + array('RelayState' => SimpleSAML_Utilities::selfURL()) + ); + } + + + /* Generate session id and save it in a cookie. */ + $sessionID = SimpleSAML_Utilities::generateID(); + + $cookieName = $amc->getCookieName(); + setcookie($cookieName, $sessionID, 0, '/', NULL, SimpleSAML_Utilities::isHTTPS(), TRUE); + + + /* Generate the authentication information. */ + + $attributes = $session->getAttributes(); + + $authData = array(); + + /* Username. */ + $usernameAttr = $amc->getUsernameAttr(); + if(!array_key_exists($usernameAttr, $attributes)) { + throw new Exception('The user doesn\'t have an attribute named \'' . $usernameAttr . + '\'. This attribute is expected to contain the username.'); + } + $authData['UserName'] = $attributes[$usernameAttr]; + + /* Groups. */ + $groupsAttr = $amc->getGroupsAttr(); + if($groupsAttr !== NULL) { + if(!array_key_exists($groupsAttr, $attributes)) { + throw new Exception('The user doesn\'t have an attribute named \'' . $groupsAttr . + '\'. This attribute is expected to contain the groups the user is a member of.'); + } + $authData['Groups'] = $attributes[$groupsAttr]; + } else { + $authData['Groups'] = array(); + } + + $authData['RemoteIP'] = $_SERVER['REMOTE_ADDR']; + + foreach($attributes as $n => $v) { + $authData['ATTR_' . $n] = $v; + } + + + /* Store the authentication data in the memcache server. */ + + $data = ''; + foreach($authData as $n => $v) { + if(is_array($v)) { + $v = implode(':', $v); + } + + $data .= $n . '=' . $v . "\r\n"; + } + + + $memcache = $amc->getMemcache(); + $memcache->set($sessionID, $data); + + /* Register logout handler. */ + $session->registerLogoutHandler('SimpleSAML/AuthMemCookie.php', 'SimpleSAML_AuthMemCookie', 'logoutHandler'); + + /* Redirect the user back to this page to signal that the login is completed. */ + SimpleSAML_Utilities::redirect(SimpleSAML_Utilities::selfURL()); +} catch(Exception $e) { + SimpleSAML_Utilities::fatalError($session->getTrackID(), 'CONFIG', $e); +} + +?> \ No newline at end of file -- GitLab