Skip to content
Snippets Groups Projects
Commit ca2f7d60 authored by Laurent Lecluse's avatar Laurent Lecluse
Browse files

Merge remote-tracking branch 'origin/master' into php84

# Conflicts:
#	composer.json
parents 0ca0c686 03a23679
No related branches found
No related tags found
No related merge requests found
Pipeline #38644 passed
Showing
with 585 additions and 158 deletions
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/authentification.iml" filepath="$PROJECT_DIR$/.idea/authentification.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MessDetectorOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PHPCSFixerOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PHPCodeSnifferOptionsConfiguration">
<option name="highlightLevel" value="WARNING" />
<option name="transferred" value="true" />
</component>
<component name="PhpProjectSharedConfiguration" php_language_level="7.4">
<option name="suggestChangeDefaultLanguageLevel" value="false" />
</component>
<component name="PhpStanOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PsalmOptionsConfiguration">
<option name="transferred" value="true" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PHPUnit">
<option name="directories">
<list>
<option value="$PROJECT_DIR$/tests" />
</list>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
\ No newline at end of file
# CHANGELOG
6.4.5
-----
- Ajout d'une garde sur la fonction Provider/Identity/Chain::getAllIdentityRoles() pour éviter le cas où $role est null
6.4.4
-----
- Authentification shibboleth : serrages de vis dans les typages et les attributs obligatoires, toilettage, doc.
- Ajout de documentation
6.4.3 (29/01/2025)
------------------
- Dépendance ZfcUser explicite
- Remplacement de Laminas\Crypt\Password\Bcrypt par ZfcUser\Password\Bcrypt
6.4.2
-----
- [Fix] Aide de vue UserUsurpationHelper : manquait le use de classe AbstractUser.
6.4.1 (14/01/2025)
------------------
- [Fix] Désactivation de l'intranavigation sur le formulaire de connexion
6.4.0 (10/01/2025)
------------------
- Passage à phpCas 1.6
- [Fix] Correction de problème de version UnicaenApp
6.3.2 (09/01/2025)
------------------
- Compatibilité OK UnicaenUtilisateur 7.0
6.3.1
-----
- [Fix] Correction en cas de namesRole ne dépendant pas d'entité AbstractRole
6.3.0
-----
......@@ -21,6 +68,10 @@
- [Fix] UserContext manipule des Laminas\Permissions\Acl\Role\RoleInterface, tous les rôles ne venant pas de la BDD
## 5.0.2
- Si CAS est le seul type d'authentification alors le lien de connexion envoie directement vers le CAS sans passer par la sélection du type
## 1.0.1 (07/02/2022)
......
***UnicaenAuth***
---
Bibliothèque unicaen/authentification
=====================================
**CHANGES**
---
Ce module ajoute à une application la possibilité d'authentifier les utilisateurs.
**5.0.2**
* Si CAS est le seul type d'authentification alors le lien de connexion envoie directement vers le CAS sans passer par la sélection du type
Quatre modes d'authentification sont disponibles :
- LDAP
- base de données
- CAS
- shibboleth
---
Ce module :
Cette bibliothèque est le résultat de l'extraction des fonctionnalités d'authentification de l'ancienne bibliothèque
[unicaen/auth](https://git.unicaen.fr/lib/unicaen/auth).
- ajoute à une application la possibilité d'identifier/authentifier l'utilisateur (LDAP, base de données ou CAS).
- fournit la possibilité à l'utilisateur de se créer un compte dans la base de données de l'application (option de config).
- fournit les fonctionnalités d'habilitation de l'utilisateur (ACL).
- Une bibliothèque de rôles éditable via une IHM
- Un système de gestion des droits avec des privilèges éditables via une IHM
- Un système d'assertions avancées pour gérer des cas complexes d'autorisations
- requiert les modules suivants :
- UnicaenApp
- ZfcUserDoctrineOrm
- phpCAS
- BjyAuthorize
## Documentation
- [Installation](./doc/installation.md)
- [Configuration](./doc/configuration.md)
- [Authentification](./doc/authentification.md)
- [Services](./doc/services.md)
- [Utilisation de la gestion des droits et privilèges](./doc/droits.md)
- [Aides de vue (view helpers)](./doc/helpers.md)
- [Authentification](doc/authentification/auth.md)
......@@ -200,18 +200,20 @@ $settings = [
'sn' => 'HTTP_SN',
'givenName' => 'HTTP_GIVENNAME',
],
/*
*/
/**
* Clés dont la présence sera requise par la bibliothèque dans la variable superglobale $_SERVER
* une fois l'authentification réussie.
*/
'required_attributes' => [
'eppn',
'mail',
'eduPersonPrincipalName',
'supannCivilite',
'displayName',
'sn | surname', // i.e. 'sn' ou 'surname'
'givenName',
'supannEtuId|supannEmpId',
'supannEmpId | supannEtuId | supannRefId',
],
*/
/**
* Configuration de la stratégie d'extraction d'un identifiant utile parmi les données d'authentification
......@@ -223,19 +225,19 @@ $settings = [
// domaine (ex: 'unicaen.fr') de l'EPPN (ex: hochonp@unicaen.fr')
'unicaen.fr' => [
'supannRefId' => [
// nom du 1er attribut recherché
// 1er attribut recherché
'name' => 'supannRefId', // ex: '{OCTOPUS:ID}1234;{ISO15693}044D1AZE7A5P80'
// pattern éventuel pour extraire la partie intéressante
'preg_match_pattern' => '|\{OCTOPUS:ID\}(\d+)|', // ex: permet d'extraire '1234'
],
'supannEmpId' => [
// nom du 2e attribut recherché, si le 1er est introuvable
// 2e attribut recherché, si le 1er est introuvable
'name' => 'supannEmpId',
// pas de pattern donc valeur brute utilisée
'preg_match_pattern' => null,
],
'supannEtuId' => [
// nom du 3e attribut recherché, si le 2e est introuvable
// 3e attribut recherché, si le 2e est introuvable
'name' => 'supannEtuId',
],
],
......
......@@ -80,10 +80,10 @@ return [
/**
* URL de déconnexion.
*/
'logout_url' => '/Shibboleth.sso/Logout?return=', // NB: '?return=' semble obligatoire!
'logout_url' => '/Shibboleth.sso/Logout?return=', // NB: '?return=' obligatoire pour pouvoir concaténer une URL de retour
/**
* Autorise l'IDP à gérer la déconnexion
* Autoriser l'IDP à gérer la déconnexion ?
*/
'idp_logout' => false,
......@@ -114,17 +114,17 @@ return [
/**
* Clés dont la présence sera requise par l'application dans la variable superglobale $_SERVER
* une fois l'authentification réussie.
*/
//'required_attributes' => [
// 'eppn',
// 'mail',
// 'eduPersonPrincipalName',
* Celles-ci sont requises d'office par la bibliothèque :
* - 'eppn',
* - 'mail',
* - 'displayName',
* - 'sn | surname', // i.e. 'sn' ou 'surname'
* - 'givenName',
* - 'supannEmpId | supannEtuId | supannRefId',
*/
'required_attributes' => [
//'supannCivilite',
// 'displayName',
// 'sn|surname', // i.e. 'sn' ou 'surname'
// 'givenName',
// 'supannEtuId|supannEmpId',
//],
],
/**
* Configuration de la stratégie d'extraction d'un identifiant utile parmi les données d'authentification
......@@ -135,19 +135,19 @@ return [
// domaine (ex: 'unicaen.fr') de l'EPPN (ex: hochonp@unicaen.fr')
// 'unicaen.fr' => [
// 'supannRefId' => [
// // nom du 1er attribut recherché
// // 1er attribut recherché
// 'name' => 'supannRefId', // ex: '{OCTOPUS:ID}1234;{ISO15693}044D1AZE7A5P80'
// // pattern éventuel pour extraire la partie intéressante
// 'preg_match_pattern' => '|\{OCTOPUS:ID\}(\d+)|', // ex: permet d'extraire '1234'
// ],
// 'supannEmpId' => [
// // nom du 2e attribut recherché
// // 2e attribut recherché, si le 1er n'a pas été trouvé
// 'name' => 'supannEmpId',
// // pas de pattern donc valeur brute utilisée
// 'preg_match_pattern' => null,
// ],
// 'supannEtuId' => [
// // nom du 3e attribut recherché
// // 3e attribut recherché, si le 2e n'a pas été trouvé
// 'name' => 'supannEtuId',
// ],
// ],
......
Authentification
================
La bibliothèque propose 4 modes d'authentification différents :
- [via la fédération d'identité Renater (Shibboleth)](auth_shib.md) : `shib` ;
- [via un serveur CAS (SSO)](auth_cas.md) : `cas` ;
- [auprès d'un annuaire LDAP](auth_ldap.md) : `ldap` ;
- [avec un compte local dans la BDD de l'application](auth_db.md) : `db`.
Plusieurs modes d'authentification peuvent être activés/proposés simultanément,
exemple : "Fédération d'identité" et "Compte local dans la BDD".
NB : Les modes `ldap` et `db` sont regroupés sous le pseudo-mode `local` du fait qu'il partage le même
formulaire de connexion.
La configuration de l'authentification se trouve sous la clé `'unicaen-auth'`.
**NB :**
- Le mode d'authentification `shib` est fortement recommandé pour que les personnes extérieures à votre SI mais
dont l'établissement fait partie de la fédération d'identité Renater puissent s'authentifier sur ESUP-SyGAL avec
leur compte établissement.
- Le mode d'authentification `db` doit obligatoirement être activé pour garantir que des personnes extérieures
à votre SI et dont l'établissement ne faisant pas partie de la fédération d'identité Renater puissent s'authentifier
sur ESUP-SyGAL (ex : codirecteurs et rapporteurs étrangers).
Usurpation d'identité
---------------------
La bibliothèque permet d'usurper l'identité d'un utilisateur, autrement dit de se faire passer pour lui.
Cette fonctionnalité est intéressante lorsqu'on fait de la documentation et/ou qu'on veut valider le bon fonctionnement
pour un rôle particulier. **Elle est bien entendu réservée à une instance de test ou de formation et pas à une instance
de production.**
Seuls les comptes utilisateurs listés dans la configuration seront habilités à usurper une identité.
```php
'unicaen-auth' => [
//...
/**
* Identifiants de connexion des utilisateurs autorisés à faire de l'usurpation d'identité.
* (NB: à réserver exclusivement aux instances de test/formation.)
*/
'usurpation_allowed_usernames' => [
'username', // format d'un compte LDAP
'e.mail@domain.fr', // format d'un compte local (BDD)
'eppn@domain.fr', // format Shibboleth
],
],
```
L'usurpation d'identité est "déclenchable" de 2 façons différentes :
- bouton à cliquer : à dessiner où vous voulez grâce à l'aide de vue `userUsurpation` (cf. UserUsurpationHelper) ;
- champ de saisie d'un identifiant de connexion : disponible dans l'encart s'affichant lorsqu'on clique sur son nom
dans le bandeau supérieur des pages de l'application.
> NB : par définition on usurpe un compte *utilisateur* donc seules les personnes existant dans la table des utilisateurs
peuvent faire l'objet d'une usurpation d'identité.
Authentification via un serveur CAS (SSO)
=========================================
Exemple de configuration (partie SANS donnée sensible) :
```php
'unicaen-auth' => [
//...
/**
* Configuration de l'authentification centralisée (CAS).
*/
'cas' => [
/**
* Ordre d'affichage du formulaire de connexion.
*/
'order' => 1,
/**
* Activation ou non de ce mode d'authentification.
*/
'enabled' => true,
/**
* Description facultative de ce mode d'authentification qui apparaîtra sur la page de connexion.
*/
'description' => "Cliquez sur le bouton ci-dessous pour accéder à l'authentification centralisée.",
],
```
Exemple de configuration (partie AVEC donnée sensible) :
```php
'unicaen-auth' => [
//...
/**
* Configuration de l'authentification centralisée (CAS).
*/
'cas' => [
/**
* Infos de connexion au serveur CAS.
*/
'connection' => [
'default' => [
'params' => [
'hostname' => 'host.domain.fr',
'port' => 443,
'version' => "2.0",
'uri' => "",
'debug' => false,
],
],
]
],
```
Adaptations à faire selon votre contexte :
- Infos de connexion au serveur CAS.
\ No newline at end of file
Authentification avec un compte local en base de données
========================================================
Ce mode d'authentification **doit** être activé.
```php
'unicaen-auth' => [
//...
/**
* Configuration de l'authentification locale (compte LDAP établissement, ou compte BDD application).
*/
'local' => [
/**
* Ordre d'affichage du formulaire de connexion.
*/
'order' => 2,
/**
* Description facultative de ce mode d'authentification qui apparaîtra sur la page de connexion.
*/
'description' => "Utilisez ce formulaire si vous possédez un compte local dédié à l'application.",
/**
* Mode d'authentification à l'aide d'un compte dans la BDD de l'application.
*/
'db' => [
/**
* Activation ou non de ce mode d'authentification.
*/
'enabled' => true, // doit être activé
],
//...
],
```
Authentification auprès d'un annuaire LDAP
==========================================
Exemple de configuration (partie SANS donnée sensible) :
```php
'unicaen-auth' => [
//...
/**
* Configuration de l'authentification locale (compte LDAP établissement, ou compte BDD application).
*/
'local' => [
/**
* Ordre d'affichage du formulaire de connexion.
*/
'order' => 2,
/**
* Description facultative de ce mode d'authentification qui apparaîtra sur la page de connexion.
*/
'description' => "Utilisez ce formulaire si vous possédez un compte LDAP établissement ou un compte local dédié à l'application.",
/**
* Mode d'authentification à l'aide d'un compte LDAP.
*/
'ldap' => [
'enabled' => true,
],
//...
],
```
En cas d'activation du mode d'authentification LDAP, la connexion à l'annuaire LDAP *avec un compte admin* ainsi
que certains paramètres de fonctionnement doivent être configurés sous la clé `'unicaen-app'`.
Exemple de configuration (partie AVEC donnée sensible) :
```php
'unicaen-app' => [
//...
/**
* Paramètres de fonctionnement LDAP.
*/
'ldap' => [
/**
* Connexion à l'annuaire LDAP (NB: compte admin requis)
*/
'connection' => [
'default' => [
'params' => [
'host' => 'host.domain.fr',
'username' => "uid=xxxxxxxxx,ou=xxxxxxxxxx,dc=domain,dc=fr",
'password' => "xxxxxxxxxxxx",
'baseDn' => "ou=xxxxxxxxxxx,dc=domain,dc=fr",
'bindRequiresDn' => true,
'accountFilterFormat' => '(&(objectClass=posixAccount)(supannAliasLogin=%s))',
]
]
],
/**
* Paramètres de fonctionnement.
*/
'dn' => [
'UTILISATEURS_BASE_DN' => 'ou=people,dc=domain,dc=fr',
'UTILISATEURS_DESACTIVES_BASE_DN' => 'ou=deactivated,dc=domain,dc=fr',
// 'GROUPS_BASE_DN' => 'ou=groups,dc=domain,dc=fr',
// 'STRUCTURES_BASE_DN' => 'ou=structures,dc=domain,dc=fr',
],
'filters' => [
'LOGIN_FILTER' => '(supannAliasLogin=%s)',
//'LOGIN_FILTER' => '(uid=%s)',
// 'UTILISATEUR_STD_FILTER' => '(|(uid=p*)(&(uid=e*)(eduPersonAffiliation=student)))',
// 'CN_FILTER' => '(cn=%s)',
// 'NAME_FILTER' => '(cn=%s*)',
// 'UID_FILTER' => '(uid=%s)',
// 'NO_INDIVIDU_FILTER' => '(supannEmpId=%08s)',
// 'AFFECTATION_FILTER' => '(&(uid=*)(eduPersonOrgUnitDN=%s))',
// 'AFFECTATION_CSTRUCT_FILTER' => '(&(uid=*)(|(ucbnSousStructure=%s;*)(supannAffectation=%s;*)))',
// 'LOGIN_OR_NAME_FILTER' => '(|(supannAliasLogin=%s)(cn=%s*))',
// 'MEMBERSHIP_FILTER' => '(memberOf=%s)',
// 'AFFECTATION_ORG_UNIT_FILTER' => '(eduPersonOrgUnitDN=%s)',
// 'AFFECTATION_ORG_UNIT_PRIMARY_FILTER' => '(eduPersonPrimaryOrgUnitDN=%s)',
// 'ROLE_FILTER' => '(supannRoleEntite=[role={SUPANN}%s][type={SUPANN}%s][code=%s]*)',
// 'PROF_STRUCTURE' => '(&(eduPersonAffiliation=teacher)(eduPersonOrgUnitDN=%s))',
// 'FILTER_STRUCTURE_DN' => '(%s)',
// 'FILTER_STRUCTURE_CODE_ENTITE' => '(supannCodeEntite=%s)',
// 'FILTER_STRUCTURE_CODE_ENTITE_PARENT' => '(supannCodeEntiteParent=%s)',
],
],
//...
],
```
Cette fois sous la clé `'unicaen-auth'`, vous devez spécifier
l'attribut LDAP à utiliser pour extraire l'identifiant de connexion (login) d'un utilisateur, exemple :
```php
'unicaen-auth' => [
'ldap' => [
/**
* Attribut LDAP utilisé pour extraire le username/login d'un utilisateur, *en minuscules*.
*/
'username' => 'supannaliaslogin',
//'username' => 'uid',
],
//...
],
```
Adaptations à faire selon votre contexte
----------------------------------------
- Infos de connexion à l'annuaire LDAP **avec un compte admin** pouvant accéder à tous les attributs LDAP :
- `'host'`
- `'username'`
- `'password'`
- Config pour le bind LDAP (vérification identifiant + mot de passe de l'utilisateur) :
- `'baseDn'` : base pour le bind, adaptez à votre annuaire.
- `'bindRequiresDn'`: laisser à `true`.
- `'accountFilterFormat'` : corriger par exemple en `'(&(objectClass=posixAccount)(uid=%s))'` si l'identifiant de
connexion de vos utilisateurs est un "uid".
- Paramètres et filtres de recherche LDAP :
- `'UTILISATEURS_BASE_DN'` : adaptez à votre annuaire, c'est sans doute pareil au `'baseDn'`ci-dessus.
- `'UTILISATEURS_DESACTIVES_BASE_DN'` : mettez la même valeur que pour `'UTILISATEURS_BASE_DN'`.
- `'LOGIN_FILTER'` : corriger par exemple en `'(uid=%s)'` si l'identifiant de
connexion de vos utilisateurs est un "uid".
Authentification via la fédération d'identité Renater (Shibboleth)
==================================================================
Exemple de configuration dans `config/autoload/xxxx.local.php` :
```php
'unicaen-auth' => [
//...
'shib' => [
/**
* Ordre d'affichage du formulaire de connexion.
*/
'order' => 1,
/**
* Activation ou non de ce mode d'authentification.
*/
'enabled' => true,
/**
* Description facultative de ce mode d'authentification qui apparaîtra sur la page de connexion.
*/
'description' =>
"<p><span class='glyphicon glyphicon-info-sign'></span> Cliquez sur le bouton ci-dessous pour accéder à l'authentification via la fédération d'identité.</p>" .
"<p><strong>Attention !</strong> Si vous possédez à la fois un compte Étudiant et un compte Personnel, vous devrez utiliser " .
"votre compte <em>Étudiant</em> pour vous authentifier...</p>",
/**
* URL de déconnexion.
*/
'logout_url' => '/Shibboleth.sso/Logout?return=', // NB: '?return=' semble obligatoire!
/**
* Autoriser l'IDP à gérer la déconnexion ?
*/
'idp_logout' => false,
/**
* Simulation d'authentification d'un utilisateur.
*/
'simulate' => [
// cf. secret.local.php
],
/**
* Alias éventuels des clés renseignées par Shibboleth dans la variable superglobale $_SERVER
* une fois l'authentification réussie.
*/
'aliases' => [
'eppn' => 'HTTP_EPPN',
'mail' => 'HTTP_MAIL',
'eduPersonPrincipalName' => 'HTTP_EPPN',
'supannRefId' => 'HTTP_SUPANNREFID',
'supannEtuId' => 'HTTP_SUPANNETUID',
'supannEmpId' => 'HTTP_SUPANNEMPID',
'supannCivilite' => 'HTTP_SUPANNCIVILITE',
'displayName' => 'HTTP_DISPLAYNAME',
'sn' => 'HTTP_SN',
'surname' => 'HTTP_SURNAME',
'givenName' => 'HTTP_GIVENNAME',
],
/**
* Clés dont la présence sera requise par l'application dans la variable superglobale $_SERVER
* une fois l'authentification réussie.
* Celles-ci sont requises d'office par la bibliothèque :
* - 'eppn',
* - 'mail',
* - 'displayName',
* - 'sn | surname', // i.e. 'sn' ou 'surname'
* - 'givenName',
* - 'supannEmpId | supannEtuId | supannRefId',
*/
'required_attributes' => [
//'supannCivilite',
],
/**
* Simulation d'authentification d'un utilisateur.
*/
/*'simulate' => [
'HTTP_EPPN' => $eppn = 'premierf@domaine.fr',
'HTTP_SUPANNEMPID' => '00012345',
'HTTP_DISPLAYNAME' => $eppn,
'HTTP_MAIL' => $eppn,
'HTTP_GIVENNAME' => 'François',
'HTTP_SN' => 'Premier',
'HTTP_SUPANNCIVILITE' => 'M.',
],*/
/**
* Configuration de la stratégie d'extraction d'un identifiant utile parmi les données d'authentification
* shibboleth.
* Ex: identifiant de l'usager au sein du référentiel établissement, transmis par l'IDP via le supannRefId.
*/
'shib_user_id_extractor' => [
// domaine de l'EPPN (ex: hochonp@unicaen.fr')
'unicaen.fr' => [
'supannEtuId' => [
// nom du 1er attribut recherché
'name' => 'supannEtuId',
// pas de pattern donc valeur brute utilisée
'preg_match_pattern' => null,
],
'supannRefId' => [
// nom du 2e attribut recherché
'name' => 'supannRefId', // ex: '{OCTOPUS:ID}1234;{ISO15693}044D137A7A5E65480'
// pattern éventuel pour extraire la partie intéressante
'preg_match_pattern' => '|\{OCTOPUS:ID\}(\d+)|', // ex: permet d'extraire '1234'
],
/*'supannEmpId' => [
// nom du 3e attribut recherché
'name' => 'supannEmpId',
// pas de pattern donc valeur brute utilisée
],*/
],
/*
// autres domaines
'univ-rouen.fr' => [
'supannEtuId' => ['name' => 'supannEtuId'],
'supannEmpId' => ['name' => 'supannEmpId'],
],
*/
// config de repli pour tous les autres domaines
'default' => [
'supannEtuId' => ['name' => 'supannEtuId'],
'supannEmpId' => ['name' => 'supannEmpId'],
],
],
/**
* URL de déconnexion.
*/
'logout_url' => '/Shibboleth.sso/Logout?return=', // NB: '?return=' obligatoire pour pouvoir concaténer une URL de retour
],
```
Cette documentation ne saurait couvrir l'installation du service Shibboleth sur un serveur, toutefois voici un
extrait de configuration Apache possible pour un Reverse Proxy / SP Shibboleth.
C'est la section `<Location /auth/shibboleth>` qui spécifie l'URL d'ESUP-SyGAL qui sera détournée par Apache pour
réaliser l'authentification Shibboleth.
```apacheconf
<VirtualHost *:443>
# ...
<Location />
AuthType shibboleth
ShibRequestSetting applicationId sygal
ShibRequestSetting requireSession false
require shibboleth
ShibUseHeaders On
</Location>
<Location /auth/shibboleth>
AuthType shibboleth
ShibRequireSession On
ShibRequestSetting applicationId sygal
ShibUseHeaders On
ShibExportAssertion On
Require valid-user
</Location>
ProxyPass / http://usygal1:80/
ProxyPassReverse / http://usygal1:80/
</VirtualHost>
```
......@@ -62,6 +62,9 @@ class Cas extends AbstractAdapter
*/
private $router;
private string $serviceBaseUrl;
/**
* @param RouteInterface $router
*/
......@@ -176,7 +179,8 @@ class Cas extends AbstractAdapter
}
// initialize phpCAS
$this->casClient->client($options['version'], $options['hostname'], $options['port'], $options['uri'], true);
$this->casClient->client($options['version'], $options['hostname'], $options['port'], $options['uri'], $this->serviceBaseUrl,true);
// no SSL validation for the CAS server
$this->casClient->setNoCasServerValidation();
......@@ -265,4 +269,12 @@ class Cas extends AbstractAdapter
],
]);
}
public function setServiceBaseUrl(string $serviceBaseUrl): void
{
$this->serviceBaseUrl = $serviceBaseUrl;
}
}
\ No newline at end of file
......@@ -4,6 +4,7 @@ namespace UnicaenAuthentification\Authentication\Adapter;
use Interop\Container\ContainerInterface;
use Laminas\Authentication\Storage\Session;
use Laminas\View\Helper\ServerUrl;
use UnicaenApp\Mapper\Ldap\People as LdapPeopleMapper;
use UnicaenAuthentification\Options\ModuleOptions;
use UnicaenAuthentification\Service\User;
......@@ -61,5 +62,10 @@ class CasAdapterFactory
/** @var LdapPeopleMapper $ldapPeopleMapper */
$ldapPeopleMapper = $container->get('ldap_people_mapper');
$adapter->setLdapPeopleMapper($ldapPeopleMapper);
/** @var ServerUrl $serverUrl */
$serverUrl = $container->get('ViewHelperManager')->get('ServerUrl');
$adapter->setServiceBaseUrl($serverUrl());
}
}
\ No newline at end of file
......@@ -3,7 +3,7 @@
namespace UnicaenAuthentification\Authentication\Adapter;
use Laminas\Authentication\Result as AuthenticationResult;
use Laminas\Crypt\Password\Bcrypt;
use ZfcUser\Password\Bcrypt;
use ZfcUser\Entity\UserInterface;
/**
......
......@@ -2,10 +2,11 @@
namespace UnicaenAuthentification\Authentication\Adapter;
use UnicaenAuthentification\Authentication\SessionIdentity;
use UnicaenAuthentification\Controller\AuthController;
use UnicaenAuthentification\Options\Traits\ModuleOptionsAwareTrait;
use UnicaenAuthentification\Service\Traits\ShibServiceAwareTrait;
use UnicaenAuthentification\Service\User;
use UnicaenAuthentification\Service\User as UserService;
use Laminas\Authentication\AuthenticationService;
use Laminas\Authentication\Result as AuthenticationResult;
use Laminas\EventManager\EventInterface;
......@@ -25,57 +26,34 @@ class Shib extends AbstractAdapter
const TYPE = 'shib';
/**
* @var string
*/
protected $type = self::TYPE;
protected AuthenticationService $authenticationService;
/**
* @var AuthenticationService
*/
protected $authenticationService;
/**
* @param AuthenticationService $authenticationService
* @return self
*/
public function setAuthenticationService(AuthenticationService $authenticationService): self
{
$this->authenticationService = $authenticationService;
return $this;
}
/**
* @var RouteInterface
*/
private $router;
private RouteInterface $router;
/**
* @param RouteInterface $router
*/
public function setRouter(RouteInterface $router)
public function setRouter(RouteInterface $router): void
{
$this->router = $router;
}
/**
* @var User
*/
private $userService;
private UserService $userService;
/**
* @param User $userService
*/
public function setUserService(User $userService)
public function setUserService(UserService $userService): void
{
$this->userService = $userService;
}
/**
* @inheritDoc
* @param \Laminas\EventManager\EventInterface $e
* @throws \Laminas\Authentication\Exception\ExceptionInterface
*/
// public function authenticate(EventInterface $e)
public function authenticate( $e)
public function authenticate($e): Response|bool
{
// NB: Dans la version 3.0.0 de zf-commons/zfc-user, cette méthode prend un EventInterface.
// Mais dans la branche 3.x, c'est un AdapterChainEvent !
......@@ -126,25 +104,25 @@ class Shib extends AbstractAdapter
->setCode(AuthenticationResult::SUCCESS)
->setMessages(['Authentication successful.']);
/* @var $userService User */
/* @var $userService UserService */
$this->userService->userAuthenticated($shibUser);
return true;
}
/**
* @inheritDoc
* @throws \Laminas\Authentication\Exception\ExceptionInterface
*/
public function logout(EventInterface $e)
public function logout(EventInterface $e): ?Response
{
$storage = $this->getStorage()->read();
if (is_array($storage)){
if (! isset($storage['identity'])) {
return;
return null;
}
}else if (!$storage instanceof SessionIdentity) {
return;
return null;
}
parent::logout($e);
......@@ -167,6 +145,7 @@ class Shib extends AbstractAdapter
$response = new Response();
$response->getHeaders()->addHeaderLine('Location', $shibbolethLogoutUrl);
$response->setStatusCode(302);
return $response;
}
......@@ -177,5 +156,7 @@ class Shib extends AbstractAdapter
* todo: supprimer cette verrue lorsque l'IDP redirigera correctement.
*/
$this->authenticationService->clearIdentity();
return null;
}
}
\ 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