diff --git a/CHANGELOG.md b/CHANGELOG.md
index 18532dfff7f828c300072de3b4db691cf1ba5dfd..d01c0ffd179069efa71a262864f3a89fefb78996 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,3 +17,8 @@
     - Correction: l'utilisateur n'était pas recherché par son username!
     - Ajout d'un validateur sur le formulaire de saisie de l'adresse électronique.
     - Vérification que le compte utilisateur est bien local.
+
+## 1.3.2 - 29/01/2019
+
+- Authentification Shibboleth: possibilité de spécifier les attributs nécessaires au fonctionnement de l'appli 
+  (clé de config `unicaen-auth` > `shibboleth` > `required_attributes`).
\ No newline at end of file
diff --git a/config/unicaen-auth.local.php.dist b/config/unicaen-auth.local.php.dist
index 0c3826e4389948b413566a9e6daac8f09fb1b38a..7fe8f5a242764852825073ef4ac5b16fe4bd5837 100644
--- a/config/unicaen-auth.local.php.dist
+++ b/config/unicaen-auth.local.php.dist
@@ -23,6 +23,18 @@ return [
                 'sn'                     => 'HTTP_SN',
                 'givenName'              => 'HTTP_GIVENNAME',
             ],
+            /*
+            'required_attributes' => [
+                'eppn',
+                'mail',
+                'eduPersonPrincipalName',
+                'supannCivilite',
+                'displayName',
+                'sn|surname', // i.e. 'sn' ou 'surname'
+                'givenName',
+                'supannEtuId|supannEmpId',
+            ],
+            */
         ],
 
         /**
diff --git a/src/UnicaenAuth/Service/ShibService.php b/src/UnicaenAuth/Service/ShibService.php
index e0df7413010c623424907afd95e63410c80409c9..513225f2ae3c603719be8c67d575f4fdbfb260a4 100644
--- a/src/UnicaenAuth/Service/ShibService.php
+++ b/src/UnicaenAuth/Service/ShibService.php
@@ -2,31 +2,36 @@
 
 namespace UnicaenAuth\Service;
 
+use Application\Exception\InvalidArgumentException;
 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
+ * Shibboleth service.
  *
  * @author Unicaen
  */
 class ShibService
 {
     /**
-     * @var ModuleOptions
+     * @var \UnicaenAuth\Entity\Shibboleth\ShibUser
      */
-    protected $options;
+    protected $authenticatedUser;
 
     /**
-     * @var \UnicaenAuth\Entity\Shibboleth\ShibUser
+     * @var array
      */
-    protected $authenticatedUser;
+    protected $shibbolethConfig = [];
+
+    /**
+     * @var array
+     */
+    protected $usurpationAllowedUsernames = [];
 
     /**
      * @return string
@@ -48,6 +53,22 @@ EOS;
         return $text;
     }
 
+    /**
+     * @param array $shibbolethConfig
+     */
+    public function setShibbolethConfig(array $shibbolethConfig)
+    {
+        $this->shibbolethConfig = $shibbolethConfig;
+    }
+
+    /**
+     * @param array $usurpationAllowedUsernames
+     */
+    public function setUsurpationAllowedUsernames(array $usurpationAllowedUsernames)
+    {
+        $this->usurpationAllowedUsernames = $usurpationAllowedUsernames;
+    }
+
     /**
      * @return ShibUser|null
      */
@@ -75,9 +96,7 @@ EOS;
      */
     public function isShibbolethEnabled()
     {
-        $options = $this->options->getShibboleth();
-
-        return array_key_exists('enable', $options) && (bool) $options['enable'];
+        return array_key_exists('enable', $this->shibbolethConfig) && (bool) $this->shibbolethConfig['enable'];
     }
 
     /**
@@ -85,28 +104,44 @@ EOS;
      */
     public function getShibbolethSimulate()
     {
-        $options = $this->options->getShibboleth();
-
-        if (! array_key_exists('simulate', $options) || ! is_array($options['simulate'])) {
+        if (! array_key_exists('simulate', $this->shibbolethConfig) || ! is_array($this->shibbolethConfig['simulate'])) {
             return [];
         }
 
-        return $options['simulate'];
+        return $this->shibbolethConfig['simulate'];
     }
 
     /**
      * @param string $attributeName
      * @return string
      */
-    public function getShibbolethAliasFor($attributeName)
+    private function getShibbolethAliasFor($attributeName)
     {
-        $options = $this->options->getShibboleth();
-
-        if (! array_key_exists('aliases', $options) || ! is_array($options['aliases']) || ! isset($options['aliases'][$attributeName])) {
+        if (! array_key_exists('aliases', $this->shibbolethConfig) ||
+            ! is_array($this->shibbolethConfig['aliases']) ||
+            ! isset($this->shibbolethConfig['aliases'][$attributeName])) {
             return null;
         }
 
-        return $options['aliases'][$attributeName];
+        return $this->shibbolethConfig['aliases'][$attributeName];
+    }
+
+    /**
+     * Retourne les alias des attributs spécifiés.
+     * Si un attribut n'a pas d'alias, c'est l'attribut lui-même qui est retourné.
+     *
+     * @param array $attributeNames
+     * @return array
+     */
+    private function getAliasedShibbolethAttributes(array $attributeNames)
+    {
+        $aliasedAttributes = [];
+        foreach ($attributeNames as $attributeName) {
+            $alias = $this->getShibbolethAliasFor($attributeName);
+            $aliasedAttributes[$attributeName] = $alias ?: $attributeName;
+        }
+
+        return $aliasedAttributes;
     }
 
     /**
@@ -116,15 +151,29 @@ EOS;
      */
     public function isSimulationActive()
     {
-        $options = $this->options->getShibboleth();
-
-        if (array_key_exists('simulate', $options) && is_array($options['simulate']) && ! empty($options['simulate'])) {
+        if (array_key_exists('simulate', $this->shibbolethConfig) &&
+            is_array($this->shibbolethConfig['simulate']) &&
+            ! empty($this->shibbolethConfig['simulate'])) {
             return true;
         }
 
         return false;
     }
 
+    /**
+     * Retourne la liste des attributs requis.
+     *
+     * @return array
+     */
+    private function getShibbolethRequiredAttributes()
+    {
+        if (! array_key_exists('required_attributes', $this->shibbolethConfig)) {
+            return [];
+        }
+
+        return (array)$this->shibbolethConfig['required_attributes'];
+    }
+
     /**
      * @return ShibUser|null
      */
@@ -186,7 +235,7 @@ EOS;
     public function activateUsurpation(ShibUser $fromShibUser, ShibUser $toShibUser)
     {
         // le login doit faire partie des usurpateurs autorisés
-        if (! in_array($fromShibUser->getUsername(), $this->options->getUsurpationAllowedUsernames())) {
+        if (! in_array($fromShibUser->getUsername(), $this->usurpationAllowedUsernames)) {
             throw new RuntimeException("Usurpation non autorisée");
         }
 
@@ -241,9 +290,53 @@ EOS;
         return new Container(ShibService::class);
     }
 
+    /**
+     * @param array $data
+     * @return array
+     */
+    private function getMissingRequiredAttributesFromData(array $data)
+    {
+        $requiredAttributes = $this->getShibbolethRequiredAttributes();
+        $missingAttributes = [];
+
+        foreach ($requiredAttributes as $requiredAttribute) {
+            // un pipe permet d'exprimer un OU logique, ex: 'supannEmpId|supannEtuId'
+            $attributes = array_map('trim', explode('|', $requiredAttribute));
+            // attributs aliasés
+            $attributes = $this->getAliasedShibbolethAttributes($attributes);
+
+            $found = false;
+            foreach (array_map('trim', $attributes) as $attribute) {
+                if (isset($data[$attribute])) {
+                    $found = true;
+                }
+            }
+            if (!$found) {
+                // attributs aliasés, dont l'un au moins est manquant, mise sous forme 'a|b'
+                $missingAttributes[] = implode('|', $attributes);
+            }
+        }
+
+        return $missingAttributes;
+    }
+
+    /**
+     * @param array $data
+     * @throws InvalidArgumentException
+     */
+    private function assertRequiredAttributesExistInData(array $data)
+    {
+        $missingAttributes = $this->getMissingRequiredAttributesFromData($data);
+
+        if (!empty($missingAttributes)) {
+            throw new InvalidArgumentException(
+                "Les attributs suivants sont manquants : " . implode(', ', $missingAttributes));
+        }
+    }
+
     /**
      * Inscrit dans le tableau $_SERVER le nécessaire pour usurper l'identité d'un utilisateur
-     * qui ce serait authentifié via Shibboleth.
+     * qui se 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é.
@@ -251,10 +344,16 @@ 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');
+        }
+
+        // pour certains attributs, on veut une valeur sensée!
         $this->setServerArrayVariable('eppn', $shibUser->getEppn());
         $this->setServerArrayVariable($keyForId, $shibUser->getId());
         $this->setServerArrayVariable('displayName', $shibUser->getDisplayName());
-        $this->setServerArrayVariable('mail', $shibUser->getEmail());
+        $this->setServerArrayVariable('mail', $shibUser->getEppn());
         $this->setServerArrayVariable('sn', $shibUser->getNom());
         $this->setServerArrayVariable('givenName', $shibUser->getPrenom());
     }
@@ -264,42 +363,19 @@ EOS;
      */
     private function createShibUserFromServerArrayData()
     {
-        $eppn = $this->getServerArrayVariable('eppn');
-
-        if ($value = $this->getServerArrayVariable('supannEtuId')) {
-            $id = $value;
-        } elseif ($value = $this->getServerArrayVariable('supannEmpId')) {
-            $id = $value;
-        } else {
-            throw new RuntimeException('Un au moins des attributs Shibboleth suivants doit exister dans $_SERVER : supannEtuId, supannEmpId.');
-        }
-
-        $mail = null;
-        if ($value = $this->getServerArrayVariable('mail')) {
-            $mail = $value;
-        }
-
-        $displayName = null;
-        if ($value = $this->getServerArrayVariable('displayName')) {
-            $displayName = $value;
-        }
-
-        $surname = null;
-        if ($value = $this->getServerArrayVariable('sn')) {
-            $surname = $value;
-        } elseif ($value = $this->getServerArrayVariable('surname')) {
-            $surname = $value;
-        }
-
-        $givenName = null;
-        if ($value = $this->getServerArrayVariable('givenName')) {
-            $givenName = $value;
+        try {
+            $this->assertRequiredAttributesExistInData($_SERVER);
+        } catch (InvalidArgumentException $e) {
+            throw new RuntimeException('Des attributs Shibboleth obligatoires font défaut dans $_SERVER.', null, $e);
         }
 
-        $civilite = null;
-        if ($value = $this->getServerArrayVariable('supannCivilite')) {
-            $civilite = $value;
-        }
+        $eppn = $this->getServerArrayVariable('eppn');
+        $id = $this->getServerArrayVariable('supannEtuId') ?: $this->getServerArrayVariable('supannEmpId');
+        $mail = $this->getServerArrayVariable('mail');
+        $displayName = $this->getServerArrayVariable('displayName');
+        $surname = $this->getServerArrayVariable('sn') ?: $this->getServerArrayVariable('surname');
+        $givenName = $this->getServerArrayVariable('givenName');
+        $civilite = $this->getServerArrayVariable('supannCivilite');
 
         $shibUser = new ShibUser();
         // propriétés de UserInterface
@@ -340,14 +416,6 @@ EOS;
         return $logoutRelativeUrl;
     }
 
-    /**
-     * @param ModuleOptions $options
-     */
-    public function setOptions(ModuleOptions $options)
-    {
-        $this->options = $options;
-    }
-
     /**
      * @param TreeRouteStack $router
      */
diff --git a/src/UnicaenAuth/Service/ShibServiceFactory.php b/src/UnicaenAuth/Service/ShibServiceFactory.php
index 418f717049ccb1b7477009a156456d05ca9062eb..ae9bed6b6138e1b268fa40098add777182bc5024 100644
--- a/src/UnicaenAuth/Service/ShibServiceFactory.php
+++ b/src/UnicaenAuth/Service/ShibServiceFactory.php
@@ -9,11 +9,12 @@ class ShibServiceFactory
 {
     public function __invoke(ServiceLocatorInterface $sl)
     {
-        /** @var ModuleOptions $options */
-        $options = $sl->get('unicaen-auth_module_options');
+        /** @var ModuleOptions $moduleOptions */
+        $moduleOptions = $sl->get('unicaen-auth_module_options');
 
         $service = new ShibService();
-        $service->setOptions($options);
+        $service->setShibbolethConfig($moduleOptions->getShibboleth());
+        $service->setUsurpationAllowedUsernames($moduleOptions->getUsurpationAllowedUsernames());
 
         return $service;
     }