diff --git a/config/module.config.php b/config/module.config.php
index 0bad6991bf0183bf6c54711b74309f4f1af448a6..b6144118d697fc96b5dc1b80767fa5748d150e4a 100644
--- a/config/module.config.php
+++ b/config/module.config.php
@@ -5,6 +5,7 @@ use UnicaenAuth\Service\ShibService;
 use UnicaenAuth\Service\ShibServiceFactory;
 use UnicaenAuth\Service\UserContextFactory;
 use UnicaenAuth\View\Helper\ShibConnectViewHelperFactory;
+use UnicaenAuth\View\Helper\UserUsurpationHelperFactory;
 
 $settings = [
     /**
@@ -122,7 +123,6 @@ return [
                 ['controller' => 'UnicaenApp\Controller\Application', 'action' => 'informatique-et-libertes', 'roles' => []],
                 ['controller' => 'UnicaenApp\Controller\Application', 'action' => 'refresh-session', 'roles' => []],
                 ['controller' => 'UnicaenAuth\Controller\Utilisateur', 'action' => 'selectionner-profil', 'roles' => []],
-                ['controller' => 'UnicaenAuth\Controller\Utilisateur', 'action' => 'usurper-identite', 'roles' => []],
 
                 ['controller' => 'UnicaenAuth\Controller\Auth', 'action' => 'shibboleth', 'roles' => []],
             ],
@@ -433,6 +433,7 @@ 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/Storage/Shib.php b/src/UnicaenAuth/Authentication/Storage/Shib.php
index 1bc25efa09bfdb760746b6a8e63aa2ec2fad23d1..2e9600d7b0b3303a1fd34ed1a8c993b6ef16c621 100644
--- a/src/UnicaenAuth/Authentication/Storage/Shib.php
+++ b/src/UnicaenAuth/Authentication/Storage/Shib.php
@@ -51,15 +51,57 @@ class Shib implements ChainableStorage, ServiceLocatorAwareInterface
      */
     public function read(ChainEvent $e)
     {
-        /** @var ShibService $shib */
-        $shib = $this->getServiceLocator()->get(ShibService::class);
-        $shibUser = $shib->getAuthenticatedUser();
+        $shibUser = $this->getAuthenticatedUser();
 
         $e->addContents('shib', $shibUser);
         
         return $shibUser;
     }
 
+    /**
+     * @return null|ShibUser
+     */
+    private function getAuthenticatedUser()
+    {
+        if (! $this->isShibbolethEnabled()) {
+            return null;
+        }
+
+        if (null !== $this->resolvedIdentity) {
+            return $this->resolvedIdentity;
+        }
+
+        /** @var ShibService $shib */
+        $shib = $this->getServiceLocator()->get(ShibService::class);
+
+        $this->resolvedIdentity = $shib->getAuthenticatedUser();
+
+        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
      *
diff --git a/src/UnicaenAuth/Controller/AuthController.php b/src/UnicaenAuth/Controller/AuthController.php
index 0bec8234c32653ee12f23b86a2e74547828658be..51fc785de01762fca73aa092b0aab8ce412a9585 100644
--- a/src/UnicaenAuth/Controller/AuthController.php
+++ b/src/UnicaenAuth/Controller/AuthController.php
@@ -3,6 +3,7 @@
 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;
@@ -23,6 +24,16 @@ 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.
+     *
+     * 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.
+     *
+     * @see ShibService::apacheConfigSnippet()
+     *
      * @return Response|array
      */
     public function shibbolethAction()
@@ -36,9 +47,14 @@ class AuthController extends AbstractActionController
             $this->zfcUserAuthentication()->getAuthService()->clearIdentity();
 
             // déconnexion Shibboleth le cas échéant
-            if ($this->shibService->isShibbolethEnable()) {
+            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
@@ -65,9 +81,4 @@ class AuthController extends AbstractActionController
 
         return $this->redirect()->toUrl($redirectUrl);
     }
-
-    public function shibboleth()
-    {
-
-    }
 }
\ No newline at end of file
diff --git a/src/UnicaenAuth/Controller/UtilisateurController.php b/src/UnicaenAuth/Controller/UtilisateurController.php
index 707cbae58285b9e207e2122e89de398ad9249c84..fbb9fc50018c26e0dcbfee1b1c16aa22b20ea837 100644
--- a/src/UnicaenAuth/Controller/UtilisateurController.php
+++ b/src/UnicaenAuth/Controller/UtilisateurController.php
@@ -2,78 +2,14 @@
 
 namespace UnicaenAuth\Controller;
 
-use UnicaenAuth\Entity\Db\UserInterface;
-use UnicaenAuth\Entity\Ldap\People;
-use UnicaenAuth\Entity\Shibboleth\ShibUser;
-use UnicaenAuth\Options\ModuleOptions;
-use Zend\Authentication\AuthenticationService;
 use Zend\Http\Request;
-use Zend\Http\Response;
 use Zend\Mvc\Controller\AbstractActionController;
 
 /**
- * 
- *
  * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
  */
 class UtilisateurController extends AbstractActionController
 {
-    /**
-     * Usurpe l'identité d'un autre utilisateur.
-     *
-     * @return Response
-     */
-    public function usurperIdentiteAction()
-    {
-        $request = $this->getRequest();
-        if (! $request instanceof Request) {
-            exit(1);
-        }
-
-        $redirection = $this->redirect()->toRoute('home');
-
-        $newIdentity = $request->getQuery('identity', $request->getPost('identity'));
-        if (! $newIdentity) {
-            return $redirection;
-        }
-
-        /** @var AuthenticationService $authenticationService */
-        $authenticationService = $this->getServiceLocator()->get(AuthenticationService::class);
-
-        /** @var ModuleOptions $options */
-        $options = $this->getServiceLocator()->get('unicaen-auth_module_options');
-
-        $currentIdentity = $authenticationService->getIdentity();
-        if (! $currentIdentity) {
-            return $redirection;
-        }
-        if (! is_array($currentIdentity)) {
-            return $redirection;
-        }
-
-        if (isset($currentIdentity['shib'])) {
-            /** @var ShibUser $currentIdentity */
-            $currentIdentity = $currentIdentity['shib'];
-        } elseif (isset($currentIdentity['ldap'])) {
-            /** @var People $currentIdentity */
-            $currentIdentity = $currentIdentity['ldap'];
-        } elseif (isset($currentIdentity['db'])) {
-            /** @var UserInterface $currentIdentity */
-            $currentIdentity = $currentIdentity['db'];
-        } else {
-            return $redirection;
-        }
-
-        $currentIdentity = $currentIdentity->getUsername();
-        if (! in_array($currentIdentity, $options->getUsurpationAllowedUsernames())) {
-            return $redirection;
-        }
-
-        $authenticationService->getStorage()->write($newIdentity);
-
-        return $redirection;
-    }
-
     /**
      * 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.
diff --git a/src/UnicaenAuth/Entity/Shibboleth/ShibUser.php b/src/UnicaenAuth/Entity/Shibboleth/ShibUser.php
index b0c785c2534ceb782d6c79b8b1285a02a7973bfb..3312082344781febd0e56333e80c4a2aaf829613 100644
--- a/src/UnicaenAuth/Entity/Shibboleth/ShibUser.php
+++ b/src/UnicaenAuth/Entity/Shibboleth/ShibUser.php
@@ -55,6 +55,16 @@ 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.
      *
diff --git a/src/UnicaenAuth/Service/ShibService.php b/src/UnicaenAuth/Service/ShibService.php
index d473dbf667ae405835a9320d2a6f37715d50277a..45cdd52de3fba4187dffdcc5cc07b22ac27af073 100644
--- a/src/UnicaenAuth/Service/ShibService.php
+++ b/src/UnicaenAuth/Service/ShibService.php
@@ -2,10 +2,14 @@
 
 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
@@ -44,10 +48,47 @@ EOS;
         return $text;
     }
 
+    /**
+     * @return ShibUser|null
+     */
+    public function getAuthenticatedUser()
+    {
+        if (! $this->isShibbolethEnabled()) {
+            return null;
+        }
+
+        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();
+        }
+
+        return $this->authenticatedUser;
+    }
+
     /**
      * @return boolean
      */
-    public function isShibbolethEnable()
+    public function isShibbolethEnabled()
     {
         $options = $this->options->getShibboleth();
 
@@ -55,24 +96,160 @@ EOS;
     }
 
     /**
-     * @return ShibUser|null
+     * @return array
      */
-    public function getAuthenticatedUser()
+    public function getShibbolethSimulate()
     {
-        if ($this->authenticatedUser === null) {
-            if (empty($_SERVER['REMOTE_USER'])) {
-                return null;
-            }
-            $this->authenticatedUser = $this->createShibUser();
+        $options = $this->options->getShibboleth();
+
+        if (! array_key_exists('simulate', $options) || ! is_array($options['simulate'])) {
+            return [];
         }
 
-        return $this->authenticatedUser;
+        return $options['simulate'];
+    }
+
+    /**
+     * Retourne true si la simulation d'un utilisateur authentifié via Shibboleth est en cours.
+     *
+     * @return bool
+     */
+    private function isSimulationActive()
+    {
+        $options = $this->options->getShibboleth();
+
+        if (array_key_exists('simulate', $options) && is_array($options['simulate']) && ! empty($options['simulate'])) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * @return $this
+     */
+    private function handleSimulation()
+    {
+        $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');
+
+        ShibService::simulateAuthenticatedUser($shibUser);
+
+        return $this;
+    }
+
+    /**
+     * 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
+     */
+    private function handleUsurpation()
+    {
+        $session = $this->getSessionContainer();
+
+        /** @var ShibUser|null $toShibUser */
+        $toShibUser = $session->offsetGet('toShibUser');
+        if ($toShibUser === null) {
+            throw new RuntimeException("Anomalie: 'toShibUser' introuvable");
+        }
+
+        static::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 static 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 ShibUser
      */
-    private function createShibUser()
+    private function createShibUserFromServerArrayData()
     {
         $eppn = $_SERVER['REMOTE_USER'];
 
@@ -81,7 +258,7 @@ EOS;
         } elseif (isset($_SERVER['supannEmpId'])) {
             $id = $_SERVER['supannEmpId'];
         } else {
-            throw new RuntimeException('Un au moins des attributs suivants doit exister dans $_SERVER : supannEtuId, supannEmpId.');
+            throw new RuntimeException('Un au moins des attributs Shibboleth suivants doit exister dans $_SERVER : supannEtuId, supannEmpId.');
         }
 
         $mail = null;
@@ -134,6 +311,10 @@ 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 65aab76944b4043dc4f522d14d2acb782f6a35ca..0fc768d899a4205cd2e15582f902ff1985e40a60 100644
--- a/src/UnicaenAuth/Service/UserContext.php
+++ b/src/UnicaenAuth/Service/UserContext.php
@@ -5,6 +5,7 @@ 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;
@@ -73,6 +74,24 @@ 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.
      *
@@ -91,6 +110,27 @@ 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 2038e8f7d86fc3d34ec46f410663bf1e508b83eb..477ddf603ee7843c61482db6866c86fcda1fa64c 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->isShibbolethEnable()) {
+        if (! $this->shibService->isShibbolethEnabled()) {
             return '';
         }
 
diff --git a/src/UnicaenAuth/View/Helper/UserInfo.php b/src/UnicaenAuth/View/Helper/UserInfo.php
index 83f28bd82b0acb6ff44708e632ac4453cde371b6..c837447870cf2e20557daf2ea1c11088abdbf09d 100644
--- a/src/UnicaenAuth/View/Helper/UserInfo.php
+++ b/src/UnicaenAuth/View/Helper/UserInfo.php
@@ -102,7 +102,11 @@ 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
new file mode 100644
index 0000000000000000000000000000000000000000..ab6d807fa7e95497c562f587ecdcaaf516be401a
--- /dev/null
+++ b/src/UnicaenAuth/View/Helper/UserUsurpationHelper.php
@@ -0,0 +1,141 @@
+<?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
new file mode 100644
index 0000000000000000000000000000000000000000..9aa21103a2f05a72c3d26c2587b9c97e9123de5d
--- /dev/null
+++ b/src/UnicaenAuth/View/Helper/UserUsurpationHelperFactory.php
@@ -0,0 +1,38 @@
+<?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