Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
lib
unicaen
auth
Commits
ff93d62a
Commit
ff93d62a
authored
May 06, 2021
by
Bertrand Gauthier
Browse files
Merge branch 'release-3.2.0'
parents
098e285b
23c62cc7
Pipeline
#9950
passed with stage
in 16 seconds
Changes
55
Pipelines
3
Hide whitespace changes
Inline
Side-by-side
CHANGELOG.md
View file @
ff93d62a
...
...
@@ -37,3 +37,11 @@ Première version officielle sous ZF3.
3.
1.2
-----
-
Aide de vue UserUsurpationHelper : ajout de la possibilité de dessiner un simple bouton.
3.
2.0
-----
-
Configuration de la stratégie d'extraction d'un identifiant utile parmi les données d'authentification shibboleth
(config 'shib_user_id_extractor').
-
Possibilité de connaître la source de l'authentification (db, ldap, cas, shib).
-
Possibilité de stopper l'usurpation en cours pour revenir à l'identité d'origine.
-
[FIX] Usurpation d'un compte local en BDD.
Module.php
View file @
ff93d62a
...
...
@@ -75,15 +75,6 @@ class Module implements AutoloaderProviderInterface, ConfigProviderInterface, Se
},
//===========================================
// verrue pour forcer le label de l'identifiant qqsoit l'options 'auth_identity_fields'
'zfcuser_login_form'
=>
function
(
$sm
)
{
$options
=
$sm
->
get
(
'zfcuser_module_options'
);
$form
=
new
Login
(
null
,
$options
);
$form
->
setInputFilter
(
new
LoginFilter
(
$options
));
$form
->
get
(
'identity'
)
->
setLabel
(
"Username"
);
return
$form
;
},
],
];
}
...
...
config/module.config.php
View file @
ff93d62a
<?php
use
UnicaenAuth\Authentication\Adapter\AdapterChainServiceFactory
;
use
UnicaenAuth\Authentication\Adapter\Cas
;
use
UnicaenAuth\Authentication\Adapter\CasAdapterFactory
;
use
UnicaenAuth\Authentication\Adapter\Db
;
use
UnicaenAuth\Authentication\Adapter\DbAdapterFactory
;
use
UnicaenAuth\Authentication\Adapter\Ldap
;
use
UnicaenAuth\Authentication\Adapter\LdapAdapterFactory
;
use
UnicaenAuth\Authentication\Adapter\LocalAdapter
;
use
UnicaenAuth\Authentication\Adapter\LocalAdapterFactory
;
use
UnicaenAuth\Authentication\Adapter\Shib
;
use
UnicaenAuth\Authentication\Adapter\ShibAdapterFactory
;
use
UnicaenAuth\Authentication\Storage\Auth
;
use
UnicaenAuth\Authentication\Storage\AuthFactory
;
use
UnicaenAuth\Authentication\Storage\DbFactory
;
use
UnicaenAuth\Authentication\Storage\LdapFactory
;
use
UnicaenAuth\Authentication\Storage\ShibFactory
;
use
UnicaenAuth\Authentication\Storage\Usurpation
;
use
UnicaenAuth\Authentication\Storage\UsurpationFactory
;
use
UnicaenAuth\Controller\AuthControllerFactory
;
use
UnicaenAuth\Controller\DroitsControllerFactory
;
use
UnicaenAuth\Controller\UtilisateurControllerFactory
;
use
UnicaenAuth\Form\CasLoginForm
;
use
UnicaenAuth\Form\CasLoginFormFactory
;
use
UnicaenAuth\Form\Droits\RoleFormFactory
;
use
UnicaenAuth\Form\LoginFormFactory
;
use
UnicaenAuth\Form\LoginForm
;
use
UnicaenAuth\Form\ShibLoginForm
;
use
UnicaenAuth\Form\ShibLoginFormFactory
;
use
UnicaenAuth\Guard\PrivilegeControllerFactory
;
...
...
@@ -59,9 +71,9 @@ use Zend\ServiceManager\Proxy\LazyServiceFactory;
$settings
=
[
/**
* Configuration de l'authentification
via la fédération d'identité (Shibboleth
).
* Configuration de l'authentification
centralisée (CAS
).
*/
'
shib
'
=>
[
'
cas
'
=>
[
/**
* Ordre d'affichage du formulaire de connexion.
*/
...
...
@@ -70,12 +82,77 @@ $settings = [
/**
* Activation ou non de ce mode d'authentification.
*/
'enabled'
=>
false
,
'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."
,
/**
* Adapter compétent pour réaliser l'authentification de l'utilisateur.
*/
'adapter'
=>
Cas
::
class
,
/**
* Service/formulaire d'authentification à utiliser.
*/
'form'
=>
CasLoginForm
::
class
,
/**
*
Description facultative de ce mode d'authentification qui apparaîtra sur le formulaire de connexion
.
*
Infos de connexion au serveur CAS
.
*/
'connection'
=>
[
'default'
=>
[
'params'
=>
[
'hostname'
=>
'host.domain.fr'
,
'port'
=>
443
,
'version'
=>
"2.0"
,
'uri'
=>
""
,
'debug'
=>
false
,
],
],
]
],
/**
* Configuration de l'authentification locale (compte LDAP établissement, ou compte BDD application).
*/
'local'
=>
[
'order'
=>
2
,
'enabled'
=>
true
,
'description'
=>
"Utilisez ce formulaire si vous possédez un compte LDAP établissement ou un compte local dédié à l'application."
,
'form'
=>
LoginForm
::
class
,
/**
* Mode d'authentification à l'aide d'un compte dans la BDD de l'application.
*/
'db'
=>
[
'enabled'
=>
true
,
// doit être activé pour que l'usurpation fonctionne (cf. Authentication/Storage/Db::read()) :-/ todo: faire mieux
'adapter'
=>
Db
::
class
,
'form'
=>
LoginForm
::
class
,
],
/**
* Mode d'authentification à l'aide d'un compte LDAP.
*/
'ldap'
=>
[
'enabled'
=>
true
,
'adapter'
=>
Ldap
::
class
,
'form'
=>
LoginForm
::
class
,
],
],
/**
* Configuration de l'authentification via la fédération d'identité (Shibboleth).
*/
'shib'
=>
[
'order'
=>
3
,
'enabled'
=>
false
,
'description'
=>
"Cliquez sur le bouton ci-dessous pour accéder à l'authentification via la fédération d'identité."
,
'adapter'
=>
Shib
::
class
,
'form'
=>
ShibLoginForm
::
class
,
/**
* URL de déconnexion.
...
...
@@ -110,68 +187,33 @@ $settings = [
'supannEtuId|supannEmpId',
],
*/
],
/**
* Configuration de l'authentification LDAP (compte établissement).
*/
'ldap'
=>
[
'order'
=>
2
,
'enabled'
=>
true
,
'description'
=>
"Utilisez ce formulaire pour vous connecter avec votre compte numérique établissement."
,
/**
* Type de substitution.
* Permet de "fusionner" les types d'authentification locale (db) et établissement (ldap) et donc leurs
* formulaires de connexion respectifs.
*/
'type'
=>
'local'
,
],
/**
* Configuration de l'authentification locale (compte propre à l'appli).
*/
'db'
=>
[
'order'
=>
3
,
'enabled'
=>
false
,
/**
* Type de substitution.
* Permet de "grouper" les types d'authentification locale (db) et établissement (ldap) sous un même
* formulaire de connexion.
*/
'type'
=>
'local'
,
/**
*
Description facultative de ce mode d'authentification qui apparaîtra sur le formulaire
d'authentification
.
*
NB: si la valeur de 'order' pour le type 'db' est supérieure à celle pour le type 'ldap',
*
c'est cette description qui sera visible
.
*
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
.
*/
'description'
=>
"Utilisez ce formulaire si vous possédez un compte local propre à l'application."
,
],
/**
* Configuration de l'authentification centralisée (CAS).
*/
'cas'
=>
[
'order'
=>
4
,
'enabled'
=>
false
,
'description'
=>
"Cliquez sur le bouton ci-dessous pour accéder à l'authentification centralisée."
,
/**
* Infos de connexion au serveur CAS.
*/
'connection'
=>
[
'default'
=>
[
'params'
=>
[
'hostname'
=>
'host.domain.fr'
,
'port'
=>
443
,
'version'
=>
"2.0"
,
'uri'
=>
""
,
'debug'
=>
false
,
'shib_user_id_extractor'
=>
[
// domaine (ex: 'unicaen.fr') de l'EPPN (ex: hochonp@unicaen.fr')
'unicaen.fr'
=>
[
[
// nom du 1er attribut recherché
'name'
=>
'supannRefId'
,
// ex: '{REFERENTIEL}1234;{ISO15693}044D1AZE7A5P80'
// pattern éventuel pour extraire la partie intéressante
'preg_match_pattern'
=>
'|\{REFERENTIEL\}(\d+)|'
,
// ex: permet d'extraire '1234'
],
[
// nom du 2e attribut recherché
'name'
=>
'supannEmpId'
,
// pas de pattern donc valeur directement utilisable
'preg_match_pattern'
=>
null
,
],
[
// nom du 3e attribut recherché
'name'
=>
'supannEtuId'
,
],
],
]
]
,
],
/**
...
...
@@ -239,9 +281,8 @@ return [
* Default value: array containing 'ZfcUser\Authentication\Adapter\Db' with priority 100
* Accepted values: array containing services that implement 'ZfcUser\Authentication\Adapter\ChainableAdapter'
*/
'auth_adapters'
=>
[
300
=>
'UnicaenAuth\Authentication\Adapter\Ldap'
,
200
=>
'UnicaenAuth\Authentication\Adapter\Db'
,
'auth_adapters'
=>
[
400
=>
LocalAdapter
::
class
,
// délègue à Db et Ldap
100
=>
'UnicaenAuth\Authentication\Adapter\Cas'
,
50
=>
'UnicaenAuth\Authentication\Adapter\Shib'
,
],
...
...
@@ -295,6 +336,8 @@ return [
[
'controller'
=>
'UnicaenApp\Controller\Application'
,
'action'
=>
'informatique-et-libertes'
,
'roles'
=>
'guest'
],
[
'controller'
=>
'UnicaenApp\Controller\Application'
,
'action'
=>
'refresh-session'
,
'roles'
=>
'guest'
],
[
'controller'
=>
'UnicaenAuth\Controller\Utilisateur'
,
'action'
=>
'selectionner-profil'
,
'roles'
=>
'guest'
],
[
'controller'
=>
'UnicaenAuth\Controller\Utilisateur'
,
'action'
=>
'usurper-identite'
,
'roles'
=>
'guest'
],
[
'controller'
=>
'UnicaenAuth\Controller\Utilisateur'
,
'action'
=>
'stopper-usurpation'
,
'roles'
=>
'guest'
],
[
'controller'
=>
'UnicaenAuth\Controller\Auth'
,
'action'
=>
'login'
,
'roles'
=>
'guest'
],
[
'controller'
=>
'UnicaenAuth\Controller\Auth'
,
'action'
=>
'authenticate'
,
'roles'
=>
'guest'
],
...
...
@@ -575,6 +618,7 @@ return [
// in /var/www/sygal/module/Application/src/Application/Controller/UtilisateurController.php on line 34
'service_manager'
=>
[
'aliases'
=>
[
'zfcuser_login_form'
=>
LoginForm
::
class
,
'Zend\Authentication\AuthenticationService'
=>
'zfcuser_auth_service'
,
'UnicaenAuth\Privilege\PrivilegeProvider'
=>
'UnicaenAuth\Service\Privilege'
,
'\UnicaenAuth\Guard\PrivilegeController'
=>
'UnicaenAuth\Guard\PrivilegeController'
,
...
...
@@ -607,6 +651,7 @@ return [
'UnicaenAuth\Service\UserContext'
=>
UserContextFactory
::
class
,
'zfcuser_user_mapper'
=>
UserMapperFactory
::
class
,
'MouchardCompleterAuth'
=>
'UnicaenAuth\Mouchard\MouchardCompleterAuthFactory'
,
LocalAdapter
::
class
=>
LocalAdapterFactory
::
class
,
'UnicaenAuth\Authentication\Adapter\Ldap'
=>
LdapAdapterFactory
::
class
,
'UnicaenAuth\Authentication\Adapter\Db'
=>
DbAdapterFactory
::
class
,
'UnicaenAuth\Authentication\Adapter\Cas'
=>
CasAdapterFactory
::
class
,
...
...
@@ -614,11 +659,16 @@ return [
'UnicaenAuth\Authentication\Storage\Db'
=>
DbFactory
::
class
,
'UnicaenAuth\Authentication\Storage\Ldap'
=>
LdapFactory
::
class
,
'UnicaenAuth\Authentication\Storage\Shib'
=>
ShibFactory
::
class
,
Usurpation
::
class
=>
UsurpationFactory
::
class
,
Auth
::
class
=>
AuthFactory
::
class
,
'UnicaenAuth\Service\User'
=>
UserFactory
::
class
,
'UnicaenAuth\Guard\PrivilegeController'
=>
PrivilegeControllerFactory
::
class
,
'UnicaenAuth\Guard\PrivilegeRoute'
=>
PrivilegeRouteFactory
::
class
,
'UnicaenAuth\Provider\Rule\PrivilegeRuleProvider'
=>
PrivilegeRuleProviderFactory
::
class
,
// verrue pour forcer le label de l'identifiant qqsoit l'options 'auth_identity_fields'
LoginForm
::
class
=>
LoginFormFactory
::
class
,
CasLoginForm
::
class
=>
CasLoginFormFactory
::
class
,
ShibLoginForm
::
class
=>
ShibLoginFormFactory
::
class
,
'ZfcUser\Authentication\Adapter\AdapterChain'
=>
AdapterChainServiceFactory
::
class
,
...
...
config/unicaen-auth.local.php.dist
View file @
ff93d62a
<?php
use
UnicaenAuth\Authentication\Adapter\Shib
;
use
UnicaenAuth\Authentication\Adapter\Cas
;
use
UnicaenAuth\Authentication\Adapter\Ldap
;
use
UnicaenAuth\Authentication\Adapter\Db
;
return
[
'unicaen-auth'
=>
[
/**
*
Authentification LDAP (compte établissement
).
*
Configuration de l'authentification centralisée (CAS
).
*/
'
ldap
'
=>
[
'
cas
'
=>
[
/**
* Ordre d'affichage du formulaire de connexion.
*/
...
...
@@ -23,39 +18,9 @@ return [
'enabled'
=>
true
,
/**
* Type de substitution.
* Permet de "fusionner" les types d'authentification applicative (db) et établissement (ldap) et donc leurs
* formulaires de connexion respectifs.
*/
'type'
=>
'local'
,
/**
* Description facultative de ce mode d'authentification qui apparaîtra sur le formulaire de connexion.
* 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 établissement."
,
],
/**
* Authentification BDD (compte dédié à l'appli).
*/
'db'
=>
[
'order'
=>
2
,
'enabled'
=>
true
,
'type'
=>
'local'
,
/**
* Description facultative de ce mode d'authentification qui apparaîtra sur le formulaire d'authentification.
* (NB: Si l'authentification LDAP est également activée, c'est cette description qui sera utilisée)
*/
'description'
=>
"Utilisez ce formulaire si vous possédez un compte local dédié à cette application."
,
],
/**
* Authentification centralisée (CAS).
*/
'cas'
=>
[
'order'
=>
3
,
'enabled'
=>
false
,
'description'
=>
"Cliquez sur le bouton ci-dessous pour accéder à l'authentification centralisée."
,
/**
* Infos de connexion au serveur CAS.
...
...
@@ -70,6 +35,28 @@ return [
'debug'
=>
false
,
],
],
]
],
/**
* Configuration de l'authentification locale (compte LDAP établissement, ou compte BDD application).
*/
'local'
=>
[
'order'
=>
2
,
'enabled'
=>
true
,
'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 dans la BDD de l'application.
*/
'db'
=>
[
'enabled'
=>
true
,
// doit être activé pour que l'usurpation fonctionne (cf. Authentication/Storage/Db::read()) :-/
],
/**
* Mode d'authentification à l'aide d'un compte LDAP.
*/
'ldap'
=>
[
'enabled'
=>
true
,
],
],
...
...
@@ -77,7 +64,7 @@ return [
* Authentification via la fédération d'identité (Shibboleth).
*/
'shib'
=>
[
'order'
=>
4
,
'order'
=>
3
,
'enabled'
=>
false
,
'description'
=>
"Cliquez sur le bouton ci-dessous pour accéder à l'authentification via la fédération d'identité. "
.
...
...
@@ -128,6 +115,33 @@ return [
// 'givenName',
// 'supannEtuId|supannEmpId',
//],
/**
* 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 (ex: 'unicaen.fr') de l'EPPN (ex: hochonp@unicaen.fr')
'unicaen.fr'
=>
[
[
// nom du 1er attribut recherché
'name'
=>
'supannRefId'
,
// ex: '{REFERENTIEL}1234;{ISO15693}044D1AZE7A5P80'
// pattern éventuel pour extraire la partie intéressante
'preg_match_pattern'
=>
'|\{REFERENTIEL\}(\d+)|'
,
// ex: permet d'extraire '1234'
],
[
// nom du 2e attribut recherché
'name'
=>
'supannEmpId'
,
// pas de pattern donc valeur directement utilisable
'preg_match_pattern'
=>
null
,
],
[
// nom du 3e attribut recherché
'name'
=>
'supannEtuId'
,
],
],
],
],
/**
...
...
src/UnicaenAuth/Authentication/Adapter/AbstractAdapter.php
View file @
ff93d62a
...
...
@@ -2,18 +2,25 @@
namespace
UnicaenAuth\Authentication\Adapter
;
use
Zend\Authentication\Storage
;
use
UnicaenAuth\Authentication\SessionIdentity
;
use
Zend\Authentication\Storage\StorageInterface
;
use
Zend\EventManager\EventInterface
;
use
Zend\EventManager\EventManagerInterface
;
use
Zend\EventManager\ListenerAggregateInterface
;
use
Zend\EventManager\ListenerAggregateTrait
;
use
ZfcUser\Authentication\Adapter\ChainableAdapter
;
abstract
class
AbstractAdapter
implements
ChainableAdapter
abstract
class
AbstractAdapter
implements
ChainableAdapter
,
ListenerAggregateInterface
{
use
ListenerAggregateTrait
;
/**
* @var string
*/
protected
$type
;
/**
* @var
Storage\
StorageInterface
* @var StorageInterface
*/
protected
$storage
;
...
...
@@ -27,29 +34,31 @@ abstract class AbstractAdapter implements ChainableAdapter
return
$this
;
}
/**
* @return string
*/
public
function
getType
():
string
{
return
$this
->
type
;
}
/**
* Returns the persistent storage handler
*
* Session storage is used by default unless a different storage adapter has been set.
*
* @return Storage\StorageInterface
* @return StorageInterface
*/
public
function
getStorage
()
public
function
getStorage
()
:
StorageInterface
{
if
(
null
===
$this
->
storage
)
{
$this
->
setStorage
(
new
Storage\Session
(
get_class
(
$this
)));
}
return
$this
->
storage
;
}
/**
* Sets the persistent storage handler
*
* @param
Storage\
StorageInterface $storage
* @return
AbstractAdapter
Provides a fluent interface
* @param StorageInterface $storage
* @return
self
Provides a fluent interface
*/
public
function
setStorage
(
Storage
\
StorageInterface
$storage
)
public
function
setStorage
(
StorageInterface
$storage
)
:
self
{
$this
->
storage
=
$storage
;
return
$this
;
...
...
@@ -60,7 +69,7 @@ abstract class AbstractAdapter implements ChainableAdapter
*
* @return bool
*/
public
function
isSatisfied
()
public
function
isSatisfied
()
:
bool
{
$storage
=
$this
->
getStorage
()
->
read
();
return
(
isset
(
$storage
[
'is_satisfied'
])
&&
true
===
$storage
[
'is_satisfied'
]);
...
...
@@ -70,13 +79,41 @@ abstract class AbstractAdapter implements ChainableAdapter
* Set if this adapter is satisfied or not
*
* @param bool $bool
* @return
AbstractAdapter
* @return
self
*/
public
function
setSatisfied
(
$bool
=
true
)
public
function
setSatisfied
(
$bool
=
true
)
:
self
{
$storage
=
$this
->
getStorage
()
->
read
()
?:
array
();
$storage
[
'is_satisfied'
]
=
$bool
;
$this
->
getStorage
()
->
write
(
$storage
);
return
$this
;
}
/**
* @param string $username
* @return SessionIdentity
*/
protected
function
createSessionIdentity
(
string
$username
):
SessionIdentity
{
return
SessionIdentity
::
newInstance
(
$username
,
$this
->
type
);
}
/**
* Called when user id logged out
*
* @param EventInterface $e
*/
public
function
logout
(
EventInterface
$e
)
{
$this
->
getStorage
()
->
clear
();
}
/**
* @inheritDoc
*/
public
function
attach
(
EventManagerInterface
$events
,
$priority
=
1
)
{
$events
->
attach
(
'authenticate'
,
[
$this
,
'authenticate'
],
$priority
);
$events
->
attach
(
'logout'
,
[
$this
,
'logout'
],
$priority
);
}
}
src/UnicaenAuth/Authentication/Adapter/AdapterChain.php
View file @
ff93d62a
...
...
@@ -22,21 +22,21 @@ class AdapterChain extends \ZfcUser\Authentication\Adapter\AdapterChain
$this
->
getEventManager
()
->
trigger
(
'authenticate.pre'
,
$e
);
$result
=
$this
->
getEventManager
()
->
triggerUntil
(
function
(
$
t
est
)
{
return
(
$tes
t
instanceof
Response
)
;
$result
=
$this
->
getEventManager
()
->
triggerUntil
(
function
(
$
r
es
ul
t
)
{
return
$result
===
true
||
$resul
t
instanceof
Response
;
},
'authenticate'
,
$e
);
if
(
$result
->
stopped
())
{
if
(
$result
->
last
()
instanceof
Response
)
{
return
$result
->
last
();
$last
=
$result
->
last
();
if
(
$last
===
true
||
$last
instanceof
Response
)
{
return
$last
;
}
throw
new
Exception\AuthenticationEventException
(
sprintf
(
'Auth event was stopped without a response. Got "%s" instead'
,
is_object
(
$result
->
last
())
?
get_class
(
$result
->
last
())
:
gettype
(
$result
->
last
())
)
);
// throw new Exception\AuthenticationEventException(
// sprintf(
// 'Auth event was stopped without a response. Got "%s" instead',
// is_object($result->last()) ? get_class($result->last()) : gettype($result->last())
// )
// );
}
if
(
$e
->
getIdentity
())
{
...
...
@@ -54,7 +54,7 @@ class AdapterChain extends \ZfcUser\Authentication\Adapter\AdapterChain
*
* @return Response|null
*/
public
function
logoutAdapters
()
public
function
logoutAdapters
()
:
?Response
{
//Adapters might need to perform additional cleanup after logout
$responseCollection
=
$this
->
getEventManager
()
->
triggerUntil
(
function
(
$test
)
{
...
...
src/UnicaenAuth/Authentication/Adapter/AdapterChainServiceFactory.php
View file @
ff93d62a
...
...
@@ -12,17 +12,14 @@ class AdapterChainServiceFactory
$chain
=
new
AdapterChain
();
$options
=
$this
->
getOptions
(
$container
);
$enabledTypes
=
array_keys
(
$options
->
getEnabledAuthTypes
());
// types d'auth activés
//iterate and attach multiple adapters and events if offered
foreach
(
$options
->
getAuthAdapters
()
as
$priority
=>
$adapterName
)
{
/** @var AbstractAdapter $adapter */
$adapter
=
$container
->
get
(
$adapterName
);
if
(
is_callable
(
array
(
$adapter
,
'authenticate'
)))
{
$chain
->
getEventManager
()
->
attach
(
'authenticate'
,
array
(
$adapter
,
'authenticate'
),
$priority
);
}
if
(
is_callable
(
array
(
$adapter
,
'logout'
)))
{
$chain
->
getEventManager
()
->
attach
(
'logout'
,
array
(
$adapter
,
'logout'
),
$priority
);
if
(
in_array
(
$adapter
->
getType
(),
$enabledTypes
))
{
$adapter
->
attach
(
$chain
->
getEventManager
());
}
}