Skip to content
Snippets Groups Projects
Commit eefbdbc4 authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

Refactorisations.

parent 30760bf8
No related branches found
No related tags found
No related merge requests found
<?php
use UnicaenAuth\Authentication\Adapter\ShibSimulatorAdapter;
use UnicaenAuth\Authentication\Storage\ShibSimulatorStorage;
use UnicaenAuth\Controller\AuthControllerFactory;
use UnicaenAuth\Service\ShibService;
use UnicaenAuth\Service\ShibServiceFactory;
......@@ -374,6 +376,7 @@ 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',
......
......@@ -3,7 +3,6 @@
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;
......@@ -25,11 +24,6 @@ class Shib implements ChainableStorage, ServiceLocatorAwareInterface
*/
protected $storage;
/**
* @var ModuleOptions
*/
protected $options;
/**
* @var ShibUser
*/
......@@ -63,10 +57,6 @@ class Shib implements ChainableStorage, ServiceLocatorAwareInterface
*/
private function getAuthenticatedUser()
{
if (! $this->isShibbolethEnabled()) {
return null;
}
if (null !== $this->resolvedIdentity) {
return $this->resolvedIdentity;
}
......@@ -79,29 +69,6 @@ class Shib implements ChainableStorage, ServiceLocatorAwareInterface
return $this->resolvedIdentity;
}
/**
* @return bool
*/
private function isShibbolethEnabled()
{
$options = $this->getModuleOptions();
$shibboleth = $options->getShibboleth();
return isset($shibboleth['enable']) && (bool) $shibboleth['enable'];
}
/**
* @return ModuleOptions
*/
private function getModuleOptions()
{
if (null === $this->options) {
$this->options = $this->getServiceLocator()->get('unicaen-auth_module_options');
}
return $this->options;
}
/**
* Writes $contents to storage
*
......
<?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
......@@ -3,7 +3,6 @@
namespace UnicaenAuth\Controller;
use UnicaenApp\Exception\RuntimeException;
use UnicaenAuth\Service\ShibService;
use UnicaenAuth\Service\Traits\ShibServiceAwareTrait;
use UnicaenAuth\Service\Traits\UserServiceAwareTrait;
use Zend\Authentication\AuthenticationService;
......@@ -24,15 +23,17 @@ class AuthController extends AbstractActionController
use UserServiceAwareTrait;
/**
* Cette action n'est exécutée qu'une fois l'authentification Shibboleth réalisée avec succès.
* Cette action peut être appelée lorsque l'authentification Shibboleth est activée
* (unicaen-auth.shibboleth.enable === true).
*
* Lorsque l'authentification Shibboleth est activée (unicaen-auth.shibboleth.enable === true),
* et que la config Apache est correcte, une requête à l'adresse correspondant à cette action
* (suite au clic sur le bouton "Authentification Shibboleth, typiquement)
* est détournée pour réaliser l'authentification.
* Ce n'est qu'une fois l'authentification réalisée avec succès que cette action entre en jeu.
* > 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.
*
* @see ShibService::apacheConfigSnippet()
* > 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
*/
......@@ -41,6 +42,38 @@ 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);
}
$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.
$this->setStoredAuthenticatedUsername($shibUser->getUsername());
$this->userService->userAuthenticated($shibUser);
return $this->redirect()->toUrl($redirectUrl);
}
/**
* Déconnexion Shibboleth.
*
* @return array|Response
*/
private function shibbolethLogout()
{
// déconnexion applicative quoiqu'il arrive
$this->zfcUserAuthentication()->getAuthAdapter()->resetAdapters();
$this->zfcUserAuthentication()->getAuthAdapter()->logoutAdapters();
......@@ -61,24 +94,17 @@ class AuthController extends AbstractActionController
}
}
$shibUser = $this->shibService->getAuthenticatedUser();
if ($shibUser === null) {
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($shibUser->getUsername());
$authService->getStorage()->write($username);
} catch (ExceptionInterface $e) {
throw new RuntimeException("Impossible d'écrire dans le storage");
}
$this->userService->userAuthenticated($shibUser);
$redirectUrl = $this->params()->fromQuery('redirect', '/');
return $this->redirect()->toUrl($redirectUrl);
}
}
\ No newline at end of file
......@@ -58,26 +58,12 @@ EOS;
}
if ($this->authenticatedUser === null) {
if (! $this->getShibbolethSimulate() && ! isset($_SERVER['REMOTE_USER'])) {
try {
Assertion::keyIsset($_SERVER, 'REMOTE_USER');
} catch (AssertionFailedException $e) {
throw new RuntimeException("La clé suivante est introuvable ou sans valeur dans \$_SERVER : 'REMOTE_USER'.");
}
}
// gestion de l'usurpation éventuelle
if ($this->isUsurpationActive()) {
$this->handleUsurpation();
}
if (empty($_SERVER['REMOTE_USER'])) {
if ($this->isSimulationActive()) {
$this->handleSimulation();
} else {
return null;
}
}
$this->authenticatedUser = $this->createShibUserFromServerArrayData();
}
......@@ -114,7 +100,7 @@ EOS;
*
* @return bool
*/
private function isSimulationActive()
public function isSimulationActive()
{
$options = $this->options->getShibboleth();
......@@ -126,10 +112,17 @@ EOS;
}
/**
* @return $this
* @return ShibUser|null
*/
private function handleSimulation()
public function handleSimulation()
{
if (! $this->isSimulationActive()) {
return null;
}
// si nécessaire
$this->handleUsurpation();
$simulate = $this->getShibbolethSimulate();
try {
......@@ -154,9 +147,9 @@ EOS;
$shibUser->setNom('Shibboleth');
$shibUser->setPrenom('Simulation');
ShibService::simulateAuthenticatedUser($shibUser);
$this->simulateAuthenticatedUser($shibUser);
return $this;
return $shibUser;
}
/**
......@@ -205,8 +198,12 @@ EOS;
/**
* @return $this
*/
private function handleUsurpation()
public function handleUsurpation()
{
if (! $this->isUsurpationActive()) {
return $this;
}
$session = $this->getSessionContainer();
/** @var ShibUser|null $toShibUser */
......@@ -215,7 +212,7 @@ EOS;
throw new RuntimeException("Anomalie: 'toShibUser' introuvable");
}
static::simulateAuthenticatedUser($toShibUser, 'supannEmpId');
$this->simulateAuthenticatedUser($toShibUser, 'supannEmpId');
return $this;
}
......@@ -236,7 +233,7 @@ EOS;
* @param string $keyForId Clé du tableau $_SERVER dans laquelle mettre l'id de l'utilsateur spécifié.
* Ex: 'supannEmpId', 'supannEtuId'.
*/
public static function simulateAuthenticatedUser(ShibUser $shibUser, $keyForId = 'supannEmpId')
public function simulateAuthenticatedUser(ShibUser $shibUser, $keyForId = 'supannEmpId')
{
$_SERVER['REMOTE_USER'] = $shibUser->getEppn();
$_SERVER[$keyForId] = $shibUser->getId();
......
<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>
Vous devez activer l'authentification Shibboleth dans la config :
Déjà, vous devez activer l'authentification Shibboleth dans la config de UnicaenAuth :
</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' :
</p>
<pre>
'unicaen-auth' => [
...
'shibboleth' => [
'enable' => true,
'simulate' => [
'eppn' => 'gauthierb@unicaen.fr',
'supannEmpId' => '00021237',
],
],
],
</pre>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment