Commit 3bbf28c1 authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

Merge remaniements

parent f6e63a4d
......@@ -69,7 +69,7 @@ class Module implements ConfigProviderInterface, ViewHelperProviderInterface, Se
$options = $services->get('unicaen-auth_module_options');
// si l'auth CAS est demandée, modif de la route de connexion pour zapper le formulaire
if ($options->getCasAuthenticationActivated()) {
if ($options->getCas()) {
/* @var $router \Zend\Mvc\Router\Http\TreeRouteStack */
$router = $services->get('router');
$router->addRoutes(array(
......@@ -78,7 +78,7 @@ class Module implements ConfigProviderInterface, ViewHelperProviderInterface, Se
'type' => 'Literal',
'priority' => 1000,
'options' => array(
'route' => '/utilisateur',
'route' => '/auth',
'defaults' => array(
'controller' => 'zfcuser',
'action' => 'index',
......@@ -156,40 +156,40 @@ class Module implements ConfigProviderInterface, ViewHelperProviderInterface, Se
{
return array(
'factories' => array(
'unicaen-auth_module_options' => function($sm) {
$config = $sm->get('Configuration');
return new Options\ModuleOptions(isset($config['unicaen-auth']) ? $config['unicaen-auth'] : array());
},
'UnicaenAuth\Authentication\Adapter\Db' => function() {
return new Authentication\Adapter\Db();
},
'UnicaenAuth\Authentication\Adapter\Ldap' => function() {
return new Authentication\Adapter\Ldap();
},
'UnicaenAuth\Authentication\Adapter\Cas' => function() {
return new Authentication\Adapter\Cas();
},
'UnicaenAuth\Authentication\Storage\Db' => function() {
return new Authentication\Storage\Db();
},
'UnicaenAuth\Authentication\Storage\Ldap' => function() {
return new Authentication\Storage\Ldap();
},
// 'unicaen-auth_module_options' => function($sm) {
// $config = $sm->get('Configuration');
// return new Options\ModuleOptions(isset($config['unicaen-auth']) ? $config['unicaen-auth'] : array());
// },
// 'UnicaenAuth\Authentication\Adapter\Db' => function() {
// return new Authentication\Adapter\Db();
// },
// 'UnicaenAuth\Authentication\Adapter\Ldap' => function() {
// return new Authentication\Adapter\Ldap();
// },
// 'UnicaenAuth\Authentication\Adapter\Cas' => function() {
// return new Authentication\Adapter\Cas();
// },
// 'UnicaenAuth\Authentication\Storage\Db' => function() {
// return new Authentication\Storage\Db();
// },
// 'UnicaenAuth\Authentication\Storage\Ldap' => function() {
// return new Authentication\Storage\Ldap();
// },
'unicaen-auth_user_service' => function () {
return new Service\User();
},
'zfcuser_auth_service' => function ($sm) {
return new \Zend\Authentication\AuthenticationService(
$sm->get('UnicaenAuth\Authentication\Storage\Mixed'),
$sm->get('ZfcUser\Authentication\Adapter\AdapterChain')
);
},
'UnicaenAuth\Authentication\Storage\Mixed' => function($sm) {
$storage = new Authentication\Storage\Mixed();
$storage->setLdapStorage($sm->get('UnicaenAuth\Authentication\Storage\Ldap'))
->setDbStorage($sm->get('UnicaenAuth\Authentication\Storage\Db'));
return $storage;
},
// 'zfcuser_auth_service' => function ($sm) {
// return new \Zend\Authentication\AuthenticationService(
// $sm->get('UnicaenAuth\Authentication\Storage\Mixed'),
// $sm->get('ZfcUser\Authentication\Adapter\AdapterChain')
// );
// },
// 'UnicaenAuth\Authentication\Storage\Mixed' => function($sm) {
// $storage = new Authentication\Storage\Mixed();
// $storage->setLdapStorage($sm->get('UnicaenAuth\Authentication\Storage\Ldap'))
// ->setDbStorage($sm->get('UnicaenAuth\Authentication\Storage\Db'));
// return $storage;
// },
'ZfcUser\Authentication\Adapter\AdapterChain' => 'UnicaenAuth\Authentication\Adapter\AdapterChainServiceFactory',
),
);
......
......@@ -45,22 +45,60 @@ $zfcuserSettings = array(
* Accepted values: boolean true or false
*/
'enable_display_name' => true,
// /**
// * Authentication Adapters
// * Specify the adapters that will be used to try and authenticate the user
// * Default value: array containing 'ZfcUser\Authentication\Adapter\Db' with priority 100
// * Accepted values: array containing services that implement 'ZfcUser\Authentication\Adapter\ChainableAdapter'
// */
// 'auth_adapters' => array(
//// 300 => 'UnicaenAuth\Authentication\Adapter\Cas',
// 200 => 'UnicaenAuth\Authentication\Adapter\Ldap',
//// 100 => 'UnicaenAuth\Authentication\Adapter\Db',
// ),
/**
* Authentication Adapters
* Specify the adapters that will be used to try and authenticate the user
* Default value: array containing 'ZfcUser\Authentication\Adapter\Db' with priority 100
* Accepted values: array containing services that implement 'ZfcUser\Authentication\Adapter\ChainableAdapter'
*/
'auth_adapters' => array(
// 100 => 'UnicaenAuth\Authentication\Service\StrategyService',
300 => 'UnicaenAuth\Authentication\Adapter\Ldap', // notifié en 1er
200 => 'UnicaenAuth\Authentication\Adapter\Db', // 2e (si échec d'authentification Ldap)
100 => 'UnicaenAuth\Authentication\Adapter\Cas', // 3e (si échec d'authentification Db)
),
);
return array(
'zfcuser' => $zfcuserSettings,
'unicaen-auth' => $settings,
'service_manager' => array(
'factories' => array(
'unicaen-auth_module_options' => function(Zend\ServiceManager\ServiceLocatorInterface $serviceLocator) {
$config = $serviceLocator->get('Config');
return new UnicaenAuth\Options\ModuleOptions(array_merge($config['zfcuser'], $config['unicaen-auth']));
},
'UnicaenAuth\Authentication\Adapter\Cas' => function() {
return new UnicaenAuth\Authentication\Adapter\Cas();
},
'UnicaenAuth\Authentication\Adapter\Ldap' => function() {
return new UnicaenAuth\Authentication\Adapter\Ldap();
},
'UnicaenAuth\Authentication\Adapter\Db' => function() {
return new UnicaenAuth\Authentication\Adapter\Db();
},
'UnicaenAuth\Authentication\Storage\Db' => function() {
return new UnicaenAuth\Authentication\Storage\Db();
},
'UnicaenAuth\Authentication\Storage\Ldap' => function() {
return new UnicaenAuth\Authentication\Storage\Ldap();
},
'UnicaenAuth\Authentication\Storage\LdapDb' => function(Zend\ServiceManager\ServiceLocatorInterface $serviceLocator) {
$storage = new UnicaenAuth\Authentication\Storage\LdapDb();
$storage->setLdapStorage($serviceLocator->get('UnicaenAuth\Authentication\Storage\Ldap'))
->setDbStorage( $serviceLocator->get('UnicaenAuth\Authentication\Storage\Db'));
return $storage;
},
'zfcuser_auth_service' => function (Zend\ServiceManager\ServiceLocatorInterface $serviceLocator) {
return new \Zend\Authentication\AuthenticationService(
$serviceLocator->get('UnicaenAuth\Authentication\Storage\LdapDb'),
$serviceLocator->get('ZfcUser\Authentication\Adapter\AdapterChain')
);
},
'UnicaenAuth\Authentication\Service\StrategyService' => 'UnicaenAuth\Authentication\Service\StrategyServiceFactory',
'UnicaenAuth\Authentication\Strategy\Strategy' => 'UnicaenAuth\Authentication\Strategy\StrategyFactory',
),
),
'controllers' => array(
'invokables' => array(
'unicaen-auth' => 'UnicaenAuth\Controller\UtilisateurController',
......@@ -103,7 +141,7 @@ return array(
'type' => 'Literal',
'priority' => 1000,
'options' => array(
'route' => '/utilisateur',
'route' => '/auth',
'defaults' => array(
'controller' => 'zfcuser',
'action' => 'index',
......
......@@ -7,18 +7,22 @@
*/
$settings = array(
/**
* Activation ou non de l'authentification CAS.
* Paramètres de connexion au serveur CAS :
* - pour désactiver l'authentification CAS, le tableau 'cas' doit être vide.
* - pour l'activer, renseigner les paramètres.
*/
'cas_authentication_activated' => false,
/**
* Connexion au serveur CAS.
*/
'cas_connection_infos' => array(
'hostname' => 'cas.unicaen.fr',
'port' => 443,
'version' => "2.0",
'uri' => "",
'debug' => false,
'cas' => array(
// 'connection' => array(
// 'default' => array(
// 'params' => array(
// 'hostname' => 'cas.unicaen.fr',
// 'port' => 443,
// 'version' => "2.0",
// 'uri' => "",
// 'debug' => false,
// ),
// ),
// ),
),
/**
* Mot de passe sésame, chiffré avec l'algo Bcrypt
......@@ -30,15 +34,13 @@ $settings = array(
* Flag indiquant si l'utilisateur authenitifié avec succès via l'annuaire LDAP doit
* être enregistré/mis à jour dans la table des utilisateurs de l'appli.
*/
'save_ldap_user_in_database' => true,
);
$zfcuserSettings = array(
'save_ldap_user_in_database' => false,
/**
* Enable registration
* Allows users to register through the website.
* Accepted values: boolean true or false
*/
'enable_registration' => true,
'enable_registration' => false,
);
/**
......@@ -46,5 +48,7 @@ $zfcuserSettings = array(
*/
return array(
'unicaen-auth' => $settings,
'zfcuser' => $zfcuserSettings,
'zfcuser' => array(
$k='enable_registration' => isset($settings[$k]) ? $settings[$k] : false,
),
);
<?php
namespace UnicaenAuth\Authentication\Adapter;
use UnicaenAuth\Options\ModuleOptions;
use Zend\Authentication\Exception\UnexpectedValueException;
use Zend\Authentication\Result as AuthenticationResult;
use \ZfcUser\Authentication\Adapter\AdapterChainEvent as AuthEvent;
use \ZfcUser\Authentication\Adapter\ChainableAdapter;
use Zend\EventManager\EventManager;
use Zend\EventManager\EventManagerAwareInterface;
use Zend\EventManager\EventManagerInterface;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;
use ZfcUser\Authentication\Adapter\AbstractAdapter;
use ZfcUser\Authentication\Adapter\AdapterChainEvent as AuthEvent;
use ZfcUser\Authentication\Adapter\ChainableAdapter;
/**
* CAS authentication adpater
*
* @author Bertrand GAUTHIER <bertrand.gauthier@unicaen.fr>
*/
class Cas extends Ldap
class Cas extends AbstractAdapter implements ServiceManagerAwareInterface, EventManagerAwareInterface
{
/**
* @var ServiceManager
*/
protected $serviceManager;
/**
* @var EventManager
*/
protected $eventManager;
/**
* @var ModuleOptions
*/
protected $options;
/**
*
* @param AuthEvent $e
......@@ -23,24 +44,28 @@ class Cas extends Ldap
*/
public function authenticate(AuthEvent $e)
{
$config = $this->getOptions()->getCas();
if (!$config) {
return; // NB: l'authentification CAS est désactivée ssi le tableau des options est vide
}
error_reporting($oldErrorReporting = error_reporting() & ~E_NOTICE);
require_once __VENDOR_DIR__ . '/gorg/phpcas/CAS.php';
if (!isset($config['connection']['default']['params'])) {
throw new \UnicaenApp\Exception("Les paramètres de connexion au serveur CAS sont invalides.");
}
$options = $config['connection']['default']['params'];
$infos = $this->getOptions()->getCasConnectionInfos();
if (array_key_exists('debug', $infos) && (bool) $infos['debug']) {
if (array_key_exists('debug', $options) && (bool) $options['debug']) {
\phpCAS::setDebug();
}
// initialize phpCAS
\phpCAS::client(
$infos['version'], $infos['hostname'], $infos['port'], $infos['uri'], true
);
\phpCAS::client($options['version'], $options['hostname'], $options['port'], $options['uri'], true);
// no SSL validation for the CAS server
\phpCAS::setNoCasServerValidation();
\phpCAS::forceAuthentication();
// at this step, the user has been authenticated by the CAS server
......@@ -50,10 +75,10 @@ class Cas extends Ldap
error_reporting($oldErrorReporting);
// nécessaire pour que le "base DN" de l'objet \Zend\Ldap\Ldap soit bien initialisé
$this->getLdapAdapter()->setUsername($identity)
->setPassword('xxx') // peu importe mais pas null
->authenticate();
// // nécessaire pour que le "base DN" de l'objet \Zend\Ldap\Ldap soit bien initialisé
// $this->getLdapAdapter()->setUsername($identity)
// ->setPassword('xxx') // peu importe mais pas null
// ->authenticate();
$e->setIdentity($identity);
$this->setSatisfied(true);
......@@ -70,4 +95,69 @@ class Cas extends Ldap
return true;
}
/**
* @param ModuleOptions $options
*/
public function setOptions(ModuleOptions $options)
{
$this->options = $options;
}
/**
* @return ModuleOptions
*/
public function getOptions()
{
if (!$this->options instanceof ModuleOptions) {
$options = array_merge(
$this->getServiceManager()->get('zfcuser_module_options')->toArray(),
$this->getServiceManager()->get('unicaen-auth_module_options')->toArray());
$this->setOptions(new ModuleOptions($options));
}
return $this->options;
}
/**
* Get service manager
*
* @return ServiceManager
*/
public function getServiceManager()
{
return $this->serviceManager;
}
/**
* Set service manager
*
* @param ServiceManager $serviceManager
* @return Ldap
*/
public function setServiceManager(ServiceManager $serviceManager)
{
$this->serviceManager = $serviceManager;
return $this;
}
/**
* Retrieve EventManager instance
*
* @return EventManagerInterface
*/
public function getEventManager()
{
return $this->eventManager;
}
/**
* Inject an EventManager instance
*
* @param EventManagerInterface $eventManager
* @return Ldap
*/
public function setEventManager(EventManagerInterface $eventManager)
{
$this->eventManager = $eventManager;
return $this;
}
}
\ No newline at end of file
......@@ -3,10 +3,11 @@ namespace UnicaenAuth\Authentication\Adapter;
use UnicaenApp\Exception;
use UnicaenAuth\Authentication\Adapter\Db;
use UnicaenAuth\Options\AuthenticationOptionsInterface;
use UnicaenAuth\Options\ModuleOptions;
use Zend\Authentication\Result as AuthenticationResult;
use Zend\Crypt\Password\Bcrypt;
use ZfcUser\Authentication\Adapter\AdapterChainEvent;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;
use ZfcUser\Authentication\Adapter\AdapterChainEvent as AuthEvent;
use ZfcUser\Entity\UserInterface;
......@@ -15,22 +16,27 @@ use ZfcUser\Entity\UserInterface;
*
* @author Bertrand GAUTHIER <bertrand.gauthier@unicaen.fr>
*/
class Db extends \ZfcUser\Authentication\Adapter\Db
class Db extends \ZfcUser\Authentication\Adapter\Db implements ServiceManagerAwareInterface
{
/**
* @var AuthenticationOptionsInterface
* @var ServiceManager
*/
protected $unicaenUserOptions;
protected $serviceManager;
/**
* Authentification.
*
* @param AdapterChainEvent $e
* @param AuthEvent $e
* @return boolean
*/
public function authenticate(AuthEvent $e)
{
$result = parent::authenticate($e);
try {
$result = parent::authenticate($e);
}
catch (\PDOException $e) {
return false;
}
// Failure, try sesame
if (false === $result) {
......@@ -43,7 +49,7 @@ class Db extends \ZfcUser\Authentication\Adapter\Db
//$credential = $this->preProcessCredential($credential);
$bcrypt = new Bcrypt();
$bcrypt->setCost($this->getOptions()->getPasswordCost());
if (($sesame = $this->getUnicaenAuthOptions()->getSesamePassword()) && $bcrypt->verify($credential, $sesame)) {
if (($sesame = $this->getOptions()->getSesamePassword()) && $bcrypt->verify($credential, $sesame)) {
// Success!
$e->setIdentity($userObject->getId());
$this->checkIfBcryptCostHasChanged($sesame, $bcrypt);
......@@ -101,28 +107,45 @@ class Db extends \ZfcUser\Authentication\Adapter\Db
}
return $this;
}
/**
* Spécifie les options de config de ce module.
*
* @param AuthenticationOptionsInterface $options
* @param ModuleOptions $options
*/
public function setUnicaenAuthOptions(AuthenticationOptionsInterface $options)
public function setOptions(ModuleOptions $options)
{
$this->unicaenUserOptions = $options;
$this->options = $options;
}
/**
* Retourne les options de config de ce module.
*
* @return AuthenticationOptionsInterface
* @return ModuleOptions
*/
public function getUnicaenAuthOptions()
public function getOptions()
{
if (!$this->unicaenUserOptions instanceof AuthenticationOptionsInterface) {
$this->setUnicaenAuthOptions($this->getServiceManager()->get('unicaen-auth_module_options'));
if (!$this->options instanceof ModuleOptions) {
$this->setOptions($this->getServiceManager()->get('unicaen-auth_module_options'));
}
return $this->unicaenUserOptions;
return $this->options;
}
/**
* Get service manager
*
* @return ServiceManager
*/
public function getServiceManager()
{
return $this->serviceManager;
}
/**
* Set service manager
*
* @param ServiceManager $serviceManager
* @return Ldap
*/
public function setServiceManager(ServiceManager $serviceManager)
{
$this->serviceManager = $serviceManager;
return $this;
}
}
\ No newline at end of file
<?php
namespace UnicaenAuth\Authentication\Adapter;
use UnicaenAuth\Options\AuthenticationOptionsInterface as AuthenticationOptionsInterface;
use Zend\Authentication\Adapter\Ldap as LdapAdapter;
use UnicaenAuth\Options\ModuleOptions;
use Zend\Authentication\Exception\UnexpectedValueException;
use Zend\Authentication\Result as AuthenticationResult;
use Zend\Authentication\Adapter\Ldap as LdapAuthAdapter;
use Zend\Crypt\Password\Bcrypt;
use Zend\EventManager\EventManager;
use Zend\EventManager\EventManagerAwareInterface;
use Zend\EventManager\EventManagerInterface;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;
use Zend\EventManager\EventManagerInterface;
use Zend\EventManager\EventManagerAwareInterface;
use \ZfcUser\Authentication\Adapter\AbstractAdapter;
use \ZfcUser\Authentication\Adapter\AdapterChainEvent as AuthEvent;
use \ZfcUser\Authentication\Adapter\ChainableAdapter;
use ZfcUser\Authentication\Adapter\AbstractAdapter;
use ZfcUser\Authentication\Adapter\AdapterChainEvent as AuthEvent;
use ZfcUser\Authentication\Adapter\ChainableAdapter;
/**
* LDAP authentication adpater
......@@ -20,31 +22,26 @@ use \ZfcUser\Authentication\Adapter\ChainableAdapter;
*/
class Ldap extends AbstractAdapter implements ServiceManagerAwareInterface, EventManagerAwareInterface
{
/**
* @var LdapAdapter
*/
protected $ldapAdapter;
/**
* @var ServiceManager
*/
protected $serviceManager;
/**
* @var \Zend\EventManager\EventManager
* @var EventManager
*/
protected $eventManager;
/**
* @var AuthenticationOptionsInterface
* @var LdapAuthAdapter
*/
protected $options;
protected $ldapAuthAdapter;
/**
* @var \ZfcUser\Options\AuthenticationOptionsInterface
* @var ModuleOptions
*/
protected $zfcUserOptions;
protected $options;
/**
*
* @param AuthEvent $e
......@@ -62,25 +59,22 @@ class Ldap extends AbstractAdapter implements ServiceManagerAwareInterface, Even
return;
}
$identity = $e->getRequest()->getPost()->get('identity');
$username = $e->getRequest()->getPost()->get('identity');
$credential = $e->getRequest()->getPost()->get('credential');
// username is the only identity source supported
$fields = $this->getZfcUserOptions()->getAuthIdentityFields();
if ('username' !== ($mode = array_shift($fields))) {
throw new UnexpectedValueException("Username is the only identity source supported by the LDAP adapter.");
}
// // username is the only identity source supported
// $fields = $this->getZfcUserOptions()->getAuthIdentityFields();
// if ('username' !== ($mode = array_shift($fields))) {
// throw new UnexpectedValueException("Username is the only identity source supported by the LDAP adapter.");
// }
// LDAP auth
$this->getLdapAdapter()->setUsername($identity)
->setPassword($credential);
$result = $this->getLdapAdapter()->authenticate();
$result = $this->getLdapAuthAdapter()->setUsername($username)->setPassword($credential)->authenticate();
$failure = true;
if (!$result->isValid()) {
// if account exists but invalid credential, and sesame password used : get LDAP entry manually
if (($sesame = $this->getOptions()->getSesamePassword())
&& AuthenticationResult::FAILURE_CREDENTIAL_INVALID === $result->getCode()) {
$bcrypt = new \Zend\Crypt\Password\Bcrypt();
if (($sesame = $this->getOptions()->getSesamePassword()) && AuthenticationResult::FAILURE_CREDENTIAL_INVALID === $result->getCode()) {
$bcrypt = new Bcrypt();
if ($bcrypt->verify($credential, $sesame)) {
// Sesame password matches
$failure = false;
......@@ -99,7 +93,7 @@ class Ldap extends AbstractAdapter implements ServiceManagerAwareInterface, Even
return false;
}
$e->setIdentity($identity);
$e->setIdentity($username);