diff --git a/config/module.config.php b/config/module.config.php index da392d13a35ae4bd9abf2a4120ed8d0e3c598213..b015ae6ff8c3e1e9babb0b2f034142249d61281e 100644 --- a/config/module.config.php +++ b/config/module.config.php @@ -1,13 +1,10 @@ <?php -use UnicaenAuth\Authentication\Adapter\ShibSimulatorAdapter; -use UnicaenAuth\Authentication\Storage\ShibSimulatorStorage; use UnicaenAuth\Controller\AuthControllerFactory; use UnicaenAuth\Service\ShibService; use UnicaenAuth\Service\ShibServiceFactory; use UnicaenAuth\Service\UserContextFactory; use UnicaenAuth\View\Helper\ShibConnectViewHelperFactory; -use UnicaenAuth\View\Helper\UserUsurpationHelperFactory; $settings = [ /** @@ -376,7 +373,6 @@ return [ 'UnicaenAuth\Authentication\Storage\Db' => 'UnicaenAuth\Authentication\Storage\Db', 'UnicaenAuth\Authentication\Storage\Ldap' => 'UnicaenAuth\Authentication\Storage\Ldap', 'UnicaenAuth\Authentication\Storage\Shib' => 'UnicaenAuth\Authentication\Storage\Shib', - 'UnicaenAuth\Authentication\Storage\ShibSimulatorStorage' => ShibSimulatorStorage::class, 'UnicaenAuth\View\RedirectionStrategy' => 'UnicaenAuth\View\RedirectionStrategy', 'UnicaenAuth\Service\User' => 'UnicaenAuth\Service\User', 'UnicaenAuth\Service\CategoriePrivilege' => 'UnicaenAuth\Service\CategoriePrivilegeService', @@ -436,7 +432,6 @@ return [ 'userInfo' => 'UnicaenAuth\View\Helper\UserInfoFactory', 'userProfileSelect' => 'UnicaenAuth\View\Helper\UserProfileSelectFactory', 'userProfileSelectRadioItem' => 'UnicaenAuth\View\Helper\UserProfileSelectRadioItemFactory', - 'userUsurpation' => UserUsurpationHelperFactory::class, 'shibConnect' => ShibConnectViewHelperFactory::class, ], 'invokables' => [ diff --git a/src/UnicaenAuth/Authentication/Adapter/Cas.php b/src/UnicaenAuth/Authentication/Adapter/Cas.php index 562446f4a4c32f5030cc144c24d18f1a9e7f9f05..a495217f8b0e954c05ac07536ab4c46ad6a8ab31 100644 --- a/src/UnicaenAuth/Authentication/Adapter/Cas.php +++ b/src/UnicaenAuth/Authentication/Adapter/Cas.php @@ -1,11 +1,9 @@ <?php - namespace UnicaenAuth\Authentication\Adapter; use phpCAS; -use UnicaenApp\Mapper\Ldap\People as LdapPeopleMapper; +use UnicaenApp\Exception; use UnicaenAuth\Options\ModuleOptions; -use UnicaenAuth\Service\User; use Zend\Authentication\Exception\UnexpectedValueException; use Zend\Authentication\Result as AuthenticationResult; use Zend\EventManager\EventManager; @@ -50,11 +48,6 @@ class Cas extends AbstractAdapter implements ServiceManagerAwareInterface, Event */ protected $casClient; - /** - * @var LdapPeopleMapper - */ - protected $ldapPeopleMapper; - /** * Réalise l'authentification. * @@ -101,12 +94,7 @@ class Cas extends AbstractAdapter implements ServiceManagerAwareInterface, Event $e->setCode(AuthenticationResult::SUCCESS) ->setMessages(['Authentication successful.']); - // recherche de l'individu dans l'annuaire LDAP (il existe forcément puisque l'auth CAS a réussi) - $ldapPeople = $this->getLdapPeopleMapper()->findOneByUsername($identity); - - /* @var $userService User */ - $userService = $this->getServiceManager()->get('unicaen-auth_user_service'); - $userService->userAuthenticated($ldapPeople); + $this->getEventManager()->trigger('userAuthenticated', $e); } /** @@ -198,31 +186,6 @@ class Cas extends AbstractAdapter implements ServiceManagerAwareInterface, Event return $this->options; } - /** - * get ldap people mapper - * - * @return LdapPeopleMapper - */ - public function getLdapPeopleMapper() - { - if (null === $this->ldapPeopleMapper) { - $this->ldapPeopleMapper = $this->getServiceManager()->get('ldap_people_mapper'); - } - return $this->ldapPeopleMapper; - } - - /** - * set ldap people mapper - * - * @param LdapPeopleMapper $mapper - * @return self - */ - public function setLdapPeopleMapper(LdapPeopleMapper $mapper) - { - $this->ldapPeopleMapper = $mapper; - return $this; - } - /** * Get service manager * diff --git a/src/UnicaenAuth/Authentication/Storage/ChainServiceFactory.php b/src/UnicaenAuth/Authentication/Storage/ChainServiceFactory.php index c15c3fc83a3a013e8c5e871b94f4c7c877f160c7..97a74366de1e3a118789247142351aa122f06a4f 100644 --- a/src/UnicaenAuth/Authentication/Storage/ChainServiceFactory.php +++ b/src/UnicaenAuth/Authentication/Storage/ChainServiceFactory.php @@ -12,15 +12,11 @@ use Zend\ServiceManager\ServiceLocatorInterface; */ class ChainServiceFactory implements FactoryInterface { - private $mandatoryStorages = [ + protected $storages = [ 200 => 'UnicaenAuth\Authentication\Storage\Ldap', 100 => 'UnicaenAuth\Authentication\Storage\Db', - 76 => 'UnicaenAuth\Authentication\Storage\ShibSimulatorStorage', - 75 => 'UnicaenAuth\Authentication\Storage\Shib', ]; - protected $storages = []; - /** * Create service * @@ -31,10 +27,7 @@ class ChainServiceFactory implements FactoryInterface { $chain = new Chain(); - $storages = $this->mandatoryStorages + $this->storages; - krsort($storages); - - foreach ($storages as $priority => $name) { + foreach ($this->storages as $priority => $name) { $storage = $serviceLocator->get($name); $chain->getEventManager()->attach('read', [$storage, 'read'], $priority); $chain->getEventManager()->attach('write', [$storage, 'write'], $priority); diff --git a/src/UnicaenAuth/Authentication/Storage/Shib.php b/src/UnicaenAuth/Authentication/Storage/Shib.php index 8d8a81c9178bf4d255581983de3db12fd6adb290..1bc25efa09bfdb760746b6a8e63aa2ec2fad23d1 100644 --- a/src/UnicaenAuth/Authentication/Storage/Shib.php +++ b/src/UnicaenAuth/Authentication/Storage/Shib.php @@ -3,6 +3,7 @@ namespace UnicaenAuth\Authentication\Storage; use UnicaenAuth\Entity\Shibboleth\ShibUser; +use UnicaenAuth\Options\ModuleOptions; use UnicaenAuth\Service\ShibService; use Zend\Authentication\Storage\Session; use Zend\Authentication\Storage\StorageInterface; @@ -23,6 +24,11 @@ class Shib implements ChainableStorage, ServiceLocatorAwareInterface * @var StorageInterface */ protected $storage; + + /** + * @var ModuleOptions + */ + protected $options; /** * @var ShibUser @@ -45,30 +51,15 @@ class Shib implements ChainableStorage, ServiceLocatorAwareInterface */ public function read(ChainEvent $e) { - $shibUser = $this->getAuthenticatedUser(); + /** @var ShibService $shib */ + $shib = $this->getServiceLocator()->get(ShibService::class); + $shibUser = $shib->getAuthenticatedUser(); $e->addContents('shib', $shibUser); return $shibUser; } - /** - * @return null|ShibUser - */ - private function getAuthenticatedUser() - { - if (null !== $this->resolvedIdentity) { - return $this->resolvedIdentity; - } - - /** @var ShibService $shib */ - $shib = $this->getServiceLocator()->get(ShibService::class); - - $this->resolvedIdentity = $shib->getAuthenticatedUser(); - - return $this->resolvedIdentity; - } - /** * Writes $contents to storage * diff --git a/src/UnicaenAuth/Authentication/Storage/ShibSimulatorStorage.php b/src/UnicaenAuth/Authentication/Storage/ShibSimulatorStorage.php deleted file mode 100644 index ffb1eabc5d211b1f44c1d7b0d45c9fae3dfaee30..0000000000000000000000000000000000000000 --- a/src/UnicaenAuth/Authentication/Storage/ShibSimulatorStorage.php +++ /dev/null @@ -1,70 +0,0 @@ -<?php - -namespace UnicaenAuth\Authentication\Storage; - -use UnicaenAuth\Service\ShibService; -use Zend\ServiceManager\ServiceLocatorAwareInterface; -use Zend\ServiceManager\ServiceLocatorAwareTrait; - -/** - * Storage permettant de simuler un utilisateur authentifié via Shibboleth. - * - * @author Unicaen - */ -class ShibSimulatorStorage implements ChainableStorage, ServiceLocatorAwareInterface -{ - use ServiceLocatorAwareTrait; - - /** - * @var ShibService - */ - protected $shibService; - - /** - * @var array - */ - protected $shibbolethOptions; - - /** - * {@inheritdoc} - */ - public function read(ChainEvent $e) - { - if (! $this->getShibService()->isShibbolethEnabled()) { - return; - } - if (! $this->getShibService()->isSimulationActive()) { - return; - } - - $this->getShibService()->handleSimulation(); - } - - /** - * {@inheritdoc} - */ - public function write(ChainEvent $e) - { - // nop - } - - /** - * {@inheritdoc} - */ - public function clear(ChainEvent $e) - { - // nop - } - - /** - * @return ShibService - */ - private function getShibService() - { - if ($this->shibService === null) { - $this->shibService = $this->serviceLocator->get(ShibService::class); - } - - return $this->shibService; - } -} \ No newline at end of file diff --git a/src/UnicaenAuth/Controller/AuthController.php b/src/UnicaenAuth/Controller/AuthController.php index 045136805e05183b05717d49000a2284a1e95182..d3b468c39e9fc06686bdbd0a30023854a27e1124 100644 --- a/src/UnicaenAuth/Controller/AuthController.php +++ b/src/UnicaenAuth/Controller/AuthController.php @@ -23,18 +23,6 @@ class AuthController extends AbstractActionController use UserServiceAwareTrait; /** - * Cette action peut être appelée lorsque l'authentification Shibboleth est activée - * (unicaen-auth.shibboleth.enable === true). - * - * > Si la config Apache de Shibboleth est correcte, une requête à l'adresse correspondant à cette action - * (suite au clic sur le bouton "Authentification Shibboleth", typiquement) - * est détournée par Apache pour réaliser l'authentification Shibboleth. - * Ce n'est qu'une fois l'authentification réalisée avec succès que cette action est appelée. - * - * > Si la config Apache de Shibboleth est incorrecte ou absente (localhost par exemple), et que la simulation - * Shibboleth est activée dans la config (unicaen-auth.shibboleth.simulate), cette action est appelée et - * la simulation est enclenchée. - * * @return Response|array */ public function shibbolethAction() @@ -42,69 +30,44 @@ class AuthController extends AbstractActionController $operation = $this->params()->fromRoute('operation'); if ($operation === 'deconnexion') { - return $this->shibbolethLogout(); - } - - $redirectUrl = $this->params()->fromQuery('redirect', '/'); - - // enclenchement de la simulation shibboleth éventuellement activée dans la config - if ($simulate = $this->shibService->getShibbolethSimulate()) { - $this->setStoredAuthenticatedUsername($simulate['eppn']); // tout simplement! - - return $this->redirect()->toUrl($redirectUrl); + // déconnexion applicative quoiqu'il arrive + $this->zfcUserAuthentication()->getAuthAdapter()->resetAdapters(); + $this->zfcUserAuthentication()->getAuthAdapter()->logoutAdapters(); + $this->zfcUserAuthentication()->getAuthService()->clearIdentity(); + + // déconnexion Shibboleth le cas échéant + if ($this->shibService->isShibbolethEnable()) { + $homeUrl = $this->url()->fromRoute('home', [], ['force_canonical' => true]); + $returnAbsoluteUrl = $this->params()->fromQuery('return', $homeUrl); + return $this->redirect()->toUrl($this->shibService->getLogoutUrl($returnAbsoluteUrl)); + } else { + return []; // une page d'aide s'affichera + } } $shibUser = $this->shibService->getAuthenticatedUser(); + if ($shibUser === null) { - return []; // une page d'aide s'affichera si les données issues de Shibboleth attendues sont absentes + return []; // une page d'aide s'affichera } - // arrivé ici, l'authentification shibboleth a été faite en bonne et due forme et a réussie. + /** @var AuthenticationService $authService */ + $authService = $this->getServiceLocator()->get('zfcuser_auth_service'); + try { + $authService->getStorage()->write($shibUser->getId()); + } catch (ExceptionInterface $e) { + throw new RuntimeException("Impossible d'écrire dans le storage"); + } - $this->setStoredAuthenticatedUsername($shibUser->getUsername()); $this->userService->userAuthenticated($shibUser); + $redirectUrl = $this->params()->fromQuery('redirect', '/'); + return $this->redirect()->toUrl($redirectUrl); } - /** - * Déconnexion Shibboleth. - * - * @return array|Response - */ - private function shibbolethLogout() + public function shibboleth() { - // déconnexion applicative quoiqu'il arrive - $this->zfcUserAuthentication()->getAuthAdapter()->resetAdapters(); - $this->zfcUserAuthentication()->getAuthAdapter()->logoutAdapters(); - $this->zfcUserAuthentication()->getAuthService()->clearIdentity(); - - // déconnexion Shibboleth le cas échéant - if ($this->shibService->isShibbolethEnabled()) { - // désactivation de l'usurpation d'identité éventuelle - $this->shibService->deactivateUsurpation(); - - // URL par défaut vers laquelle on redirige après déconnexion : accueil - $homeUrl = $this->url()->fromRoute('home', [], ['force_canonical' => true]); - $returnAbsoluteUrl = $this->params()->fromQuery('return', $homeUrl); - - return $this->redirect()->toUrl($this->shibService->getLogoutUrl($returnAbsoluteUrl)); - } else { - return []; // une page d'aide s'affichera - } - } - /** - * @param string $username - */ - private function setStoredAuthenticatedUsername($username) - { - /** @var AuthenticationService $authService */ - $authService = $this->getServiceLocator()->get('zfcuser_auth_service'); - try { - $authService->getStorage()->write($username); - } catch (ExceptionInterface $e) { - throw new RuntimeException("Impossible d'écrire dans le storage"); - } } } \ No newline at end of file diff --git a/src/UnicaenAuth/Controller/UtilisateurController.php b/src/UnicaenAuth/Controller/UtilisateurController.php index 18bccc48d3dc9eae2113c5cd38dae6767dd741d6..e8b1b01e70f8b5933d7ddd9f35f3e6b39b98b13f 100644 --- a/src/UnicaenAuth/Controller/UtilisateurController.php +++ b/src/UnicaenAuth/Controller/UtilisateurController.php @@ -2,30 +2,16 @@ namespace UnicaenAuth\Controller; -use UnicaenApp\Exception\RuntimeException; -use UnicaenApp\Mapper\Ldap\People as LdapPeopleMapper; -use UnicaenAuth\Entity\Db\AbstractUser; -use UnicaenAuth\Entity\Ldap\People; -use UnicaenAuth\Entity\Shibboleth\ShibUser; -use UnicaenAuth\Options\ModuleOptions; -use UnicaenAuth\Service\ShibService; -use UnicaenAuth\Service\UserContext; -use Zend\Authentication\AuthenticationService; use Zend\Http\Request; -use Zend\Http\Response; use Zend\Mvc\Controller\AbstractActionController; -use ZfcUser\Mapper\User as UserMapper; /** + * + * * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr> */ class UtilisateurController extends AbstractActionController { - /** - * @var LdapPeopleMapper - */ - protected $ldapPeopleMapper; - /** * Traite les requêtes AJAX POST de sélection d'un profil utilisateur. * La sélection est mémorisé en session par le service AuthUserContext. @@ -59,127 +45,12 @@ class UtilisateurController extends AbstractActionController return false; } - + /** - * Usurpe l'identité d'un autre utilisateur. - * - * @return Response - */ - public function usurperIdentiteAction() - { - $request = $this->getRequest(); - if (! $request instanceof Request) { - exit(1); - } - - $newIdentity = $request->getQuery('identity', $request->getPost('identity')); - if (! $newIdentity) { - return $this->redirect()->toRoute('home'); - } - - /** @var AuthenticationService $authenticationService */ - $authenticationService = $this->getServiceLocator()->get(AuthenticationService::class); - - $currentIdentity = $authenticationService->getIdentity(); - if (! $currentIdentity || ! is_array($currentIdentity)) { - return $this->redirect()->toRoute('home'); - } - - if (isset($currentIdentity['ldap'])) { - // si l'identifiant demandé contient un @, on estime qu'il s'agit d'un eppn shibboleth : on autorise pas le mélange des genres! - // todo: faire mieux - if (strpos($newIdentity, '@') !== false) { - throw new RuntimeException("Usurpation Shibboleth interdite depuis une authentification LDAP"); - } - /** @var People $currentIdentity */ - $currentIdentity = $currentIdentity['ldap']; - - // vérif existence de l'individu dans l'annuaire LDAP - $ldapPeople = $this->getLdapPeopleMapper()->findOneByUsername($newIdentity); - if (!$ldapPeople) { - throw new RuntimeException("Identifiant LDAP inconnu"); - } - } elseif (isset($currentIdentity['shib'])) { - // si l'identifiant demandé ne contient pas @, on estime qu'il s'agit d'un identifiant LDAP : on autorise pas le mélange des genres! - // todo: faire mieux - if (strpos($newIdentity, '@') === false) { - throw new RuntimeException("Usurpation LDAP interdite depuis une authentification Shibboleth"); - } - /** @var ShibUser $currentIdentity */ - $currentIdentity = $currentIdentity['shib']; - } - else { - return $this->redirect()->toRoute('home'); - } - - // seuls les logins spécifiés dans la config sont habilités à usurper des identités - /** @var ModuleOptions $options */ - $options = $this->getServiceLocator()->get('unicaen-auth_module_options'); - if (! in_array($currentIdentity->getUsername(), $options->getUsurpationAllowedUsernames())) { - throw new RuntimeException("Usurpation non explicitement autorisée"); - } - - // cuisine spéciale pour Shibboleth - if ($currentIdentity instanceof ShibUser) { - $fromShibUser = $currentIdentity; - $toShibUser = $this->createShibUserFromUtilisateurUsername($newIdentity); - /** @var ShibService $shibService */ - $shibService = $this->getServiceLocator()->get(ShibService::class); - $shibService->activateUsurpation($fromShibUser, $toShibUser); - } - - $authenticationService->getStorage()->write($newIdentity); - - return $this->redirect()->toRoute('home'); - } - - /** - * Recherche l'utilisateur dont le login est spécifié puis instancie un ShibUser à partir - * des attributs de cet utilisateur. - * - * @param string $username Ex tartempion@unicaen.fr - * @return ShibUser - */ - protected function createShibUserFromUtilisateurUsername($username) - { - /** @var AbstractUser $utilisateur */ - $utilisateur = $this->getUserMapper()->findByUsername($username); - if ($utilisateur === null) { - throw new RuntimeException("L'utilisateur '$username' n'existe pas dans la table des utilisateurs"); - } - - $shibUser = new ShibUser(); - $shibUser->setEppn($utilisateur->getUsername()); - $shibUser->setId(uniqid()); // peut pas mieux faire pour l'instant - $shibUser->setDisplayName($utilisateur->getDisplayName()); - $shibUser->setEmail($utilisateur->getEmail()); - $shibUser->setNom('?'); // peut pas mieux faire pour l'instant - $shibUser->setPrenom('?'); // peut pas mieux faire pour l'instant - - return $shibUser; - } - - /** - * @return UserMapper - */ - public function getUserMapper() - { - return $this->getServiceLocator()->get('zfcuser_user_mapper'); - } - - /** - * @return UserContext + * @return \UnicaenAuth\Service\UserContext */ protected function getAuthUserContextService() { return $this->getServiceLocator()->get('AuthUserContext'); } - - /** - * @return LdapPeopleMapper - */ - public function getLdapPeopleMapper() - { - return $this->serviceLocator->get('ldap_people_mapper'); - } } \ No newline at end of file diff --git a/src/UnicaenAuth/Entity/Shibboleth/ShibUser.php b/src/UnicaenAuth/Entity/Shibboleth/ShibUser.php index 3312082344781febd0e56333e80c4a2aaf829613..82c4114695736d22317fa3a2ca7c94449869e324 100644 --- a/src/UnicaenAuth/Entity/Shibboleth/ShibUser.php +++ b/src/UnicaenAuth/Entity/Shibboleth/ShibUser.php @@ -55,16 +55,6 @@ class ShibUser implements UserInterface return $this->getUsername(); } - /** - * Set eduPersoPrincipalName (EPPN). - * - * @param string $eppn eduPersoPrincipalName (EPPN), ex: 'gauthierb@unicaen.fr' - */ - public function setEppn($eppn) - { - $this->setUsername($eppn); - } - /** * Get id. * @@ -166,7 +156,7 @@ class ShibUser implements UserInterface */ public function getPrenom() { - return $this->prenom; + return $this->givenName; } /** @@ -178,7 +168,7 @@ class ShibUser implements UserInterface } /** - * @return string|null + * @return string */ public function getCivilite() { @@ -186,9 +176,9 @@ class ShibUser implements UserInterface } /** - * @param string|null $civilite + * @param string $civilite */ - public function setCivilite($civilite = null) + public function setCivilite($civilite) { $this->civilite = $civilite; } diff --git a/src/UnicaenAuth/Service/ShibService.php b/src/UnicaenAuth/Service/ShibService.php index c21da8671ba60f24fa38d84a5209365e576442e8..902e3f55c0eb97eb5fc52843e8040f68b164762f 100644 --- a/src/UnicaenAuth/Service/ShibService.php +++ b/src/UnicaenAuth/Service/ShibService.php @@ -2,14 +2,10 @@ namespace UnicaenAuth\Service; -use Assert\Assertion; -use Assert\AssertionFailedException; -use UnicaenApp\Exception\LogicException; use UnicaenApp\Exception\RuntimeException; use UnicaenAuth\Entity\Shibboleth\ShibUser; use UnicaenAuth\Options\ModuleOptions; use Zend\Mvc\Router\Http\TreeRouteStack; -use Zend\Session\Container; /** * Shibboleth service @@ -48,205 +44,35 @@ EOS; return $text; } - /** - * @return ShibUser|null - */ - public function getAuthenticatedUser() - { - if (! $this->isShibbolethEnabled()) { - return null; - } - - if ($this->authenticatedUser === null) { - // gestion de l'usurpation éventuelle - $this->handleUsurpation(); - - if (empty($_SERVER['REMOTE_USER'])) { - return null; - } - - $this->authenticatedUser = $this->createShibUserFromServerArrayData(); - } - - return $this->authenticatedUser; - } - /** * @return boolean */ - public function isShibbolethEnabled() + public function isShibbolethEnable() { $options = $this->options->getShibboleth(); return array_key_exists('enable', $options) && (bool) $options['enable']; } - /** - * @return array - */ - public function getShibbolethSimulate() - { - $options = $this->options->getShibboleth(); - - if (! array_key_exists('simulate', $options) || ! is_array($options['simulate'])) { - return []; - } - - return $options['simulate']; - } - - /** - * Retourne true si la simulation d'un utilisateur authentifié via Shibboleth est en cours. - * - * @return bool - */ - public function isSimulationActive() - { - $options = $this->options->getShibboleth(); - - if (array_key_exists('simulate', $options) && is_array($options['simulate']) && ! empty($options['simulate'])) { - return true; - } - - return false; - } - /** * @return ShibUser|null */ - public function handleSimulation() - { - if (! $this->isSimulationActive()) { - return null; - } - - // si nécessaire - $this->handleUsurpation(); - - $simulate = $this->getShibbolethSimulate(); - - try { - Assertion::keyIsset($simulate, 'eppn', - "Clé 'eppn' introuvable ou sans valeur dans l'option 'unicaen-auth.shibboleth.simulate'"); - Assertion::eq(count(array_intersect($keys = ['supannEmpId', 'supannEtuId'], array_keys($simulate))), 1, - "L'une ou l'autre de ces clés doit être présente dans l'option 'unicaen-auth.shibboleth.simulate': " . - implode(', ', $keys)); - } catch (AssertionFailedException $e) { - throw new LogicException("Configuration erronée", null, $e); - } - - $eppn = $simulate['eppn']; - $supannId = $simulate['supannEmpId'] ?: $simulate['supannEtuId']; - $email = isset($simulate['email']) ? $simulate['email'] : null; - - $shibUser = new ShibUser(); - $shibUser->setEppn($eppn); - $shibUser->setId($supannId); - $shibUser->setDisplayName("$eppn ($supannId)"); - $shibUser->setEmail($email); - $shibUser->setNom('Shibboleth'); - $shibUser->setPrenom('Simulation'); - - $this->simulateAuthenticatedUser($shibUser); - - return $shibUser; - } - - /** - * Retourne true si les données stockées en session indiquent qu'une usurpation d'identité Shibboleth est en cours. - * - * @return bool - */ - private function isUsurpationActive() - { - return $this->getSessionContainer()->offsetExists('fromShibUser'); - } - - /** - * @param ShibUser $fromShibUser - * @param ShibUser $toShibUser - * @return self - */ - public function activateUsurpation(ShibUser $fromShibUser, ShibUser $toShibUser) - { - // le login doit faire partie des usurpateurs autorisés - if (! in_array($fromShibUser->getUsername(), $this->options->getUsurpationAllowedUsernames())) { - throw new RuntimeException("Usurpation non autorisée"); - } - - $session = $this->getSessionContainer(); - $session->offsetSet('fromShibUser', $fromShibUser); - $session->offsetSet('toShibUser', $toShibUser); - - return $this; - } - - /** - * Suppression des données stockées en session concernant l'usurpation d'identité Shibboleth. - * - * @return self - */ - public function deactivateUsurpation() - { - $session = $this->getSessionContainer(); - $session->offsetUnset('fromShibUser'); - $session->offsetUnset('toShibUser'); - - return $this; - } - - /** - * @return $this - */ - public function handleUsurpation() + public function getAuthenticatedUser() { - if (! $this->isUsurpationActive()) { - return $this; - } - - $session = $this->getSessionContainer(); - - /** @var ShibUser|null $toShibUser */ - $toShibUser = $session->offsetGet('toShibUser'); - if ($toShibUser === null) { - throw new RuntimeException("Anomalie: 'toShibUser' introuvable"); + if ($this->authenticatedUser === null) { + if (empty($_SERVER['REMOTE_USER'])) { + return null; + } + $this->authenticatedUser = $this->createShibUser(); } - $this->simulateAuthenticatedUser($toShibUser, 'supannEmpId'); - - return $this; - } - - /** - * @return Container - */ - private function getSessionContainer() - { - return new Container(ShibService::class); - } - - /** - * Inscrit dans le tableau $_SERVER le nécessaire pour usurper l'identité d'un utilisateur - * qui ce serait authentifié via Shibboleth. - * - * @param ShibUser $shibUser Utilisateur dont on veut usurper l'identité. - * @param string $keyForId Clé du tableau $_SERVER dans laquelle mettre l'id de l'utilsateur spécifié. - * Ex: 'supannEmpId', 'supannEtuId'. - */ - public function simulateAuthenticatedUser(ShibUser $shibUser, $keyForId = 'supannEmpId') - { - $_SERVER['REMOTE_USER'] = $shibUser->getEppn(); - $_SERVER[$keyForId] = $shibUser->getId(); - $_SERVER['displayName'] = $shibUser->getDisplayName(); - $_SERVER['mail'] = $shibUser->getEmail(); - $_SERVER['sn'] = $shibUser->getNom(); - $_SERVER['givenName'] = $shibUser->getPrenom(); + return $this->authenticatedUser; } /** * @return ShibUser */ - private function createShibUserFromServerArrayData() + private function createShibUser() { $eppn = $_SERVER['REMOTE_USER']; @@ -255,7 +81,7 @@ EOS; } elseif (isset($_SERVER['supannEmpId'])) { $id = $_SERVER['supannEmpId']; } else { - throw new RuntimeException('Un au moins des attributs Shibboleth suivants doit exister dans $_SERVER : supannEtuId, supannEmpId.'); + throw new RuntimeException('Un au moins des attributs suivants doivent exister dans $_SERVER : supannEtuId, supannEmpId.'); } $mail = null; @@ -268,34 +94,11 @@ EOS; $displayName = $_SERVER['displayName']; } - $surname = null; - if (isset($_SERVER['sn'])) { - $surname = $_SERVER['sn']; - } elseif (isset($_SERVER['surname'])) { - $surname = $_SERVER['surname']; - } - - $givenName = null; - if (isset($_SERVER['givenName'])) { - $givenName = $_SERVER['givenName']; - } - - $civilite = null; - if (isset($_SERVER['supannCivilite'])) { - $civilite = $_SERVER['supannCivilite']; - } - $shibUser = new ShibUser(); - // propriétés de UserInterface $shibUser->setId($id); $shibUser->setUsername($eppn); $shibUser->setDisplayName($displayName); $shibUser->setEmail($mail); - $shibUser->setPassword(null); - // autres propriétés - $shibUser->setNom($surname); - $shibUser->setPrenom($givenName); - $shibUser->setCivilite($civilite); return $shibUser; } @@ -308,10 +111,6 @@ EOS; */ public function getLogoutUrl($returnAbsoluteUrl = null) { - if ($this->getShibbolethSimulate()) { - return '/'; - } - $logoutRelativeUrl = '/Shibboleth.sso/Logout?return='; // NB: '?return=' semble obligatoire! if ($returnAbsoluteUrl) { diff --git a/src/UnicaenAuth/Service/UserContext.php b/src/UnicaenAuth/Service/UserContext.php index 0fc768d899a4205cd2e15582f902ff1985e40a60..65aab76944b4043dc4f522d14d2acb782f6a35ca 100644 --- a/src/UnicaenAuth/Service/UserContext.php +++ b/src/UnicaenAuth/Service/UserContext.php @@ -5,7 +5,6 @@ namespace UnicaenAuth\Service; use BjyAuthorize\Acl\Role; use UnicaenApp\Exception\RuntimeException; use UnicaenApp\Traits\SessionContainerTrait; -use UnicaenAuth\Entity\Shibboleth\ShibUser; use UnicaenAuth\Event\UserRoleSelectedEvent; use UnicaenAuth\Provider\Identity\Chain; use Zend\EventManager\EventManagerAwareInterface; @@ -74,24 +73,6 @@ class UserContext extends AbstractService implements EventManagerAwareInterface - /** - * Retourne l'éventuel utilisateur Shibboleth courant. - * - * @return ShibUser|null - */ - public function getShibUser() - { - if (($identity = $this->getIdentity())) { - if (isset($identity['shib']) && $identity['shib'] instanceof ShibUser) { - return $identity['shib']; - } - } - - return null; - } - - - /** * Retourne les données d'identité correspondant à l'utilisateur courant. * @@ -110,27 +91,6 @@ class UserContext extends AbstractService implements EventManagerAwareInterface } - /** - * Retourne l'identifiant de connexion de l'utilisateur courant. - * - * @return string|null - */ - public function getIdentityUsername() - { - if ($user = $this->getShibUser()) { - return $user->getUsername(); - } - if ($user = $this->getLdapUser()) { - return $user->getUsername(); - } - if ($user = $this->getDbUser()) { - return $user->getUsername(); - } - - return null; - } - - /** * @param string $roleId diff --git a/src/UnicaenAuth/View/Helper/ShibConnectViewHelper.php b/src/UnicaenAuth/View/Helper/ShibConnectViewHelper.php index 477ddf603ee7843c61482db6866c86fcda1fa64c..2038e8f7d86fc3d34ec46f410663bf1e508b83eb 100644 --- a/src/UnicaenAuth/View/Helper/ShibConnectViewHelper.php +++ b/src/UnicaenAuth/View/Helper/ShibConnectViewHelper.php @@ -34,7 +34,7 @@ class ShibConnectViewHelper extends AbstractHelper */ private function render() { - if (! $this->shibService->isShibbolethEnabled()) { + if (! $this->shibService->isShibbolethEnable()) { return ''; } diff --git a/src/UnicaenAuth/View/Helper/UserInfo.php b/src/UnicaenAuth/View/Helper/UserInfo.php index c837447870cf2e20557daf2ea1c11088abdbf09d..83f28bd82b0acb6ff44708e632ac4453cde371b6 100644 --- a/src/UnicaenAuth/View/Helper/UserInfo.php +++ b/src/UnicaenAuth/View/Helper/UserInfo.php @@ -102,11 +102,7 @@ class UserInfo extends UserAbstract } $out .= $aucuneAffDispo; } - - // formulaire d'usurpation d'identité - $userUsurpationHelper = $this->view->plugin('userUsurpation'); /* @var $userUsurpationHelper \UnicaenAuth\View\Helper\UserUsurpationHelper */ - $out .= $userUsurpationHelper(); - + return $out; } diff --git a/src/UnicaenAuth/View/Helper/UserUsurpationHelper.php b/src/UnicaenAuth/View/Helper/UserUsurpationHelper.php deleted file mode 100644 index ab6d807fa7e95497c562f587ecdcaaf516be401a..0000000000000000000000000000000000000000 --- a/src/UnicaenAuth/View/Helper/UserUsurpationHelper.php +++ /dev/null @@ -1,141 +0,0 @@ -<?php - -namespace UnicaenAuth\View\Helper; - -use UnicaenApp\Form\View\Helper\FormControlGroup; -use UnicaenAuth\Options\ModuleOptions; -use Zend\Form\Element\Submit; -use Zend\Form\Element\Text; -use Zend\Form\Form; -use Zend\Form\View\Helper\Form as FormHelper; -use Zend\View\Renderer\PhpRenderer; - -/** - * Aide de vue permettant de saisir et valider le login de l'utilisateur dont on veut usurper l'identité. - * - * @author Bertrand GAUTHIER <bertrand.gauthier@unicaen.fr> - */ -class UserUsurpationHelper extends UserAbstract -{ - /** - * @var PhpRenderer - */ - protected $view; - - /** - * @var ModuleOptions - */ - protected $moduleOptions; - - /** - * @var string - */ - private $url; - - /** - * @var bool - */ - private $usurpationEnabled = false; - - /** - * Point d'entrée. - * - * @return self - */ - public function __invoke() - { - return $this; - } - - /** - * Retourne le code HTML généré par cette aide de vue. - * - * @return string - */ - public function __toString() - { - if (! $this->usurpationEnabled) { - return ''; - } - - /** @var FormHelper $formHelper */ - $formHelper = $this->view->plugin('form'); - /** @var FormControlGroup $formControlGroupHelper */ - $formControlGroupHelper = $this->view->plugin('formControlGroup'); - - $form = new Form('user-usurpation-form'); - $form->setAttributes([ - 'class' => 'user-usurpation-form', - 'action' => $this->url, - ]); - - $input = new Text('identity'); - $input->setAttributes([ - 'id' => 'user-usurpation-input', - 'placeholder' => "Identifiant utilisateur", - ]); - - $submit = new Submit('submit'); - $submit->setValue("Usurper"); - $submit->setAttributes([ - 'class' => 'user-usurpation-submit btn btn-info', - ]); - - $html = ''; - $html .= $formHelper->openTag($form); - $html .= "<div><strong>Usurpation d'identité :</strong></div>"; - $html .= $formControlGroupHelper->__invoke($input); - $html .= $formControlGroupHelper->__invoke($submit); - $html .= $formHelper->closeTag(); - - $html .= <<<EOS -<script> - $(".user-usurpation-form").submit(function() { - $("body *").css('cursor', 'wait'); - }); - var input = $("#user-usurpation-input").on('input', function() { - updateUsurpationSubmit(); - }); - function updateUsurpationSubmit() { - $(".user-usurpation-submit").prop("disabled", input.val().length === 0); - } - updateUsurpationSubmit(); -</script> -EOS; - - return $html; - } - - /** - * @param string $url - * @return $this - */ - public function setUrl($url) - { - $this->url = $url; - - return $this; - } - - /** - * @param ModuleOptions $moduleOptions - * @return self - */ - public function setModuleOptions(ModuleOptions $moduleOptions) - { - $this->moduleOptions = $moduleOptions; - - return $this; - } - - /** - * @param bool $usurpationEnabled - * @return self - */ - public function setUsurpationEnabled($usurpationEnabled = true) - { - $this->usurpationEnabled = $usurpationEnabled; - - return $this; - } -} \ No newline at end of file diff --git a/src/UnicaenAuth/View/Helper/UserUsurpationHelperFactory.php b/src/UnicaenAuth/View/Helper/UserUsurpationHelperFactory.php deleted file mode 100644 index 9aa21103a2f05a72c3d26c2587b9c97e9123de5d..0000000000000000000000000000000000000000 --- a/src/UnicaenAuth/View/Helper/UserUsurpationHelperFactory.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php - -namespace UnicaenAuth\View\Helper; - -use UnicaenAuth\Options\ModuleOptions; -use UnicaenAuth\Service\UserContext; -use Zend\View\Helper\Url; -use Zend\View\HelperPluginManager; - -class UserUsurpationHelperFactory -{ - /** - * @param HelperPluginManager $hpm - * @return UserUsurpationHelper - */ - public function __invoke(HelperPluginManager $hpm) - { - /** @var Url $urlHelper */ - $urlHelper = $hpm->get('url'); - $url = $urlHelper->__invoke('utilisateur/default', ['action' => 'usurper-identite']); - - /** @var UserContext $userContextService */ - $userContextService = $hpm->getServiceLocator()->get('authUserContext'); - - /** @var ModuleOptions $moduleOptions */ - $moduleOptions = $hpm->getServiceLocator()->get('unicaen-auth_module_options'); - - $usurpationAllowed = in_array( - $userContextService->getIdentityUsername(), - $moduleOptions->getUsurpationAllowedUsernames()); - - $helper = new UserUsurpationHelper($userContextService); - $helper->setUrl($url); - $helper->setUsurpationEnabled($usurpationAllowed); - - return $helper; - } -} \ No newline at end of file diff --git a/view/unicaen-auth/auth/shibboleth.phtml b/view/unicaen-auth/auth/shibboleth.phtml index aeb1c638e32a4865322cae6c4692ebb5ceddd833..63addc60275602b3b9b0d546d1d8adce1b6543ee 100644 --- a/view/unicaen-auth/auth/shibboleth.phtml +++ b/view/unicaen-auth/auth/shibboleth.phtml @@ -1,41 +1,23 @@ <h1 class="page-header">Authentification Shibboleth</h1> + <p> Si vous arrivez sur cette page, c'est sans doute que vous cherchez à utiliser l'authentification Shibboleth, mais qu'elle est mal configurée ! </p> -<h2>Configuration pour Shibboleth</h2> <p> - Déjà, vous devez activer l'authentification Shibboleth dans la config de UnicaenAuth : + Vous devez activer l'authentification Shibboleth dans la config : </p> <pre> 'unicaen-auth' => [ ... 'shibboleth' => [ - 'enable' => true, + 'enable' => true ], - ], + ]; </pre> -<p> - Et voici ce que vous devez ajouter dans la configuration Apache de votre site : -</p> -<pre><?php echo htmlspecialchars(\UnicaenAuth\Service\ShibService::apacheConfigSnippet()) ?></pre> - -<h2>Autre solution : simuler une authentification Shibboleth</h2> <p> - Il est possible de faire comme si un utilisateur s'était connecté via Shibboleth. - Cela se fait via la clé de config 'simulate' : + Et voici ce que vous devez ajouter dans la configuration Apache de votre site : </p> -<pre> - 'unicaen-auth' => [ - ... - 'shibboleth' => [ - 'enable' => true, - 'simulate' => [ - 'eppn' => 'gauthierb@unicaen.fr', - 'supannEmpId' => '00021237', - ], - ], - ], -</pre> \ No newline at end of file +<pre><?php echo htmlspecialchars(\UnicaenAuth\Service\ShibService::apacheConfigSnippet()) ?></pre> \ No newline at end of file