diff --git a/config/module.config.php b/config/module.config.php index 52902653c1ad69f1fddd88132421772a4f32f35e..bdf061af9de56d95f5fe5b1de9fd7a234381b9b4 100644 --- a/config/module.config.php +++ b/config/module.config.php @@ -1,6 +1,5 @@ <?php -use UnicaenAuth\Authentication\Storage\ShibSimulatorStorage; use UnicaenAuth\Controller\AuthControllerFactory; use UnicaenAuth\Service\ShibService; use UnicaenAuth\Service\ShibServiceFactory; @@ -424,7 +423,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', diff --git a/src/UnicaenAuth/Authentication/Storage/ChainServiceFactory.php b/src/UnicaenAuth/Authentication/Storage/ChainServiceFactory.php index 647d4c4a8c486f4239931e64cda37633fc9857a8..02fbd70ee4a0532749427c7ca83deb86be0a7314 100644 --- a/src/UnicaenAuth/Authentication/Storage/ChainServiceFactory.php +++ b/src/UnicaenAuth/Authentication/Storage/ChainServiceFactory.php @@ -16,7 +16,6 @@ class ChainServiceFactory implements FactoryInterface private $mandatoryStorages = [ 200 => 'UnicaenAuth\Authentication\Storage\Ldap', 100 => 'UnicaenAuth\Authentication\Storage\Db', - 76 => 'UnicaenAuth\Authentication\Storage\ShibSimulatorStorage', 75 => 'UnicaenAuth\Authentication\Storage\Shib', ]; 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 643d6d1bb9ab909715bbb39e86684c779f5ef331..79856b6264bd6d878f26f3eeaeb685c961227c03 100644 --- a/src/UnicaenAuth/Controller/AuthController.php +++ b/src/UnicaenAuth/Controller/AuthController.php @@ -55,19 +55,12 @@ class AuthController extends AbstractActionController $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); - } - $shibUser = $this->shibService->getAuthenticatedUser(); if ($shibUser === null) { return []; // une page d'aide s'affichera si les données issues de Shibboleth attendues sont absentes } - // arrivé ici, l'authentification shibboleth a été faite en bonne et due forme et a réussie. + // arrivé ici, l'authentification shibboleth a été faite (réellement ou simulée) et a réussie. $this->setStoredAuthenticatedUsername($shibUser->getUsername()); $this->userService->userAuthenticated($shibUser); diff --git a/src/UnicaenAuth/Service/ShibService.php b/src/UnicaenAuth/Service/ShibService.php index dc374e4cde1161426cd6479b847a2b5a99468659..df7b7ff4ed2bb6fbfc9ca21c30b598c2506bd3be 100644 --- a/src/UnicaenAuth/Service/ShibService.php +++ b/src/UnicaenAuth/Service/ShibService.php @@ -2,9 +2,9 @@ namespace UnicaenAuth\Service; -use InvalidArgumentException; use Assert\Assertion; use Assert\AssertionFailedException; +use InvalidArgumentException; use UnicaenApp\Exception\LogicException; use UnicaenApp\Exception\RuntimeException; use UnicaenAuth\Entity\Shibboleth\ShibUser; @@ -79,11 +79,12 @@ EOS; } if ($this->authenticatedUser === null) { - // gestion de l'usurpation éventuelle + + // activation éventuelle de l'usurpation $this->handleUsurpation(); - if (! $this->getServerArrayVariable('eppn')) { - return null; - } + + // activation éventuelle de la simulation + $this->handleSimulation(); $this->authenticatedUser = $this->createShibUserFromServerArrayData(); } @@ -175,48 +176,55 @@ EOS; } /** - * @return ShibUser|null + * */ public function handleSimulation() { if (! $this->isSimulationActive()) { - return null; + return; } - // 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::contains($simulate['eppn'], '@', - "L'eppn '" . $simulate['eppn'] . "' n'est pas de la forme 'id@domaine' attendue (ex: 'tartempion@unicaen.fr')"); - 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)); + $shibUser = $this->createShibUserFromSimulationData(); } 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; + $this->simulateAuthenticatedUser($shibUser); + } + + /** + * @return ShibUser + * @throws AssertionFailedException + */ + private function createShibUserFromSimulationData() + { + $data = $this->getShibbolethSimulate(); + + $this->assertRequiredAttributesExistInData($data); + + $eppn = $this->getValueFromShibData('eppn', $data); + $supannId = $this->getValueFromShibData('supannEmpId', $data) ?: $this->getValueFromShibData('supannEtuId', $data); + $email = $this->getValueFromShibData('mail', $data); + $displayName = $this->getValueFromShibData('displayName', $data); + $givenName = $this->getValueFromShibData('givenName', $data); + $surname = $this->getValueFromShibData('sn', $data); + $civilite = $this->getValueFromShibData('supannCivilite', $data); + + Assertion::contains($eppn, '@', "L'eppn '" . $eppn . "' n'est pas de la forme 'id@domaine' attendue (ex: 'tartempion@unicaen.fr')"); $shibUser = new ShibUser(); $shibUser->setEppn($eppn); $shibUser->setId($supannId); - $shibUser->setDisplayName("$eppn ($supannId)"); + $shibUser->setDisplayName($displayName); $shibUser->setEmail($email); - $shibUser->setNom('Shibboleth'); - $shibUser->setPrenom('Simulation'); - - $this->simulateAuthenticatedUser($shibUser); + $shibUser->setNom($surname); + $shibUser->setPrenom($givenName); + $shibUser->setCivilite($civilite); return $shibUser; } - + /** * Retourne true si les données stockées en session indiquent qu'une usurpation d'identité Shibboleth est en cours. * @@ -344,10 +352,14 @@ EOS; */ public function simulateAuthenticatedUser(ShibUser $shibUser, $keyForId = 'supannEmpId') { - // on s'assure que tous les attributs obligatoires ont une valeur - foreach ($this->getShibbolethRequiredAttributes() as $attribute) { - $this->setServerArrayVariable($attribute, 'qqchose'); - } +// // on s'assure que tous les attributs obligatoires ont une valeur +// foreach ($this->getShibbolethRequiredAttributes() as $requiredAttribute) { +// // un pipe permet d'exprimer un OU logique, ex: 'supannEmpId|supannEtuId' +// $attributes = array_map('trim', explode('|', $requiredAttribute)); +// foreach ($attributes as $attribute) { +// $this->setServerArrayVariable($attribute, 'qqchose'); +// } +// } // pour certains attributs, on veut une valeur sensée! $this->setServerArrayVariable('eppn', $shibUser->getEppn()); @@ -356,6 +368,7 @@ EOS; $this->setServerArrayVariable('mail', $shibUser->getEppn()); $this->setServerArrayVariable('sn', $shibUser->getNom()); $this->setServerArrayVariable('givenName', $shibUser->getPrenom()); + $this->setServerArrayVariable('supannCivilite', $shibUser->getCivilite()); } /** @@ -461,6 +474,22 @@ EOS; ]); } + /** + * @param string $name + * @param array $data + * @return string + */ + private function getValueFromShibData($name, array $data) + { + $key = $this->getShibbolethAliasFor($name) ?: $name; + + if (! array_key_exists($key, $data)) { + return null; + } + + return $data[$key]; + } + /** * @param string $name * @param string $value