Skip to content
Snippets Groups Projects
Select Git revision
  • d90b86ec2d690ea2f7f1424cafdf1506dd679aca
  • master default protected
  • 5.x
  • ll-php8-bs5
  • release_5_bs5
  • ll-php8
  • 4.x
  • laminas_migration
  • release_1.0.0.2
  • release_4.0.0
  • release_3.2.8
  • bootstrap4_migration
  • 1.0.0.3
  • 6.0.7
  • 6.0.6
  • 6.0.5
  • 6.0.4
  • 6.0.3
  • 6.0.2
  • 6.0.1
  • 5.1.1
  • 6.0.0
  • 5.1.0
  • 5.0.0
  • 4.0.2
  • 3.2.11
  • 4.0.1
  • 3.2.10
  • 4.0.0
  • 1.0.0.2
  • 3.2.9
  • 3.2.8
32 results

Cas.php

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    Cas.php 8.28 KiB
    <?php
    
    namespace UnicaenAuth\Authentication\Adapter;
    
    use phpCAS;
    use UnicaenApp\Mapper\Ldap\People as LdapPeopleMapper;
    use UnicaenApp\ServiceManager\ServiceLocatorAwareInterface;
    use UnicaenAuth\Options\ModuleOptions;
    use UnicaenAuth\Service\User;
    use Zend\Authentication\Exception\UnexpectedValueException;
    use Zend\Authentication\Result as AuthenticationResult;
    use Zend\EventManager\EventManager;
    use Zend\EventManager\EventManagerAwareInterface;
    use Zend\EventManager\EventManagerInterface;
    use Zend\Mvc\Router\Http\TreeRouteStack;
    use Zend\ServiceManager\ServiceLocatorAwareTrait;
    use ZfcUser\Authentication\Adapter\AbstractAdapter;
    use ZfcUser\Authentication\Adapter\AdapterChainEvent as AuthEvent;
    use ZfcUser\Authentication\Adapter\ChainableAdapter;
    
    /**
     * CAS authentication adpater
     *
     * @author Bertrand GAUTHIER <bertrand.gauthier@unicaen.fr>
     */
    class Cas extends AbstractAdapter implements EventManagerAwareInterface, ServiceLocatorAwareInterface
    {
        use ServiceLocatorAwareTrait;
    
        /**
         * @var EventManager
         */
        protected $eventManager;
    
        /**
         * @var ModuleOptions
         */
        protected $options;
    
        /**
         * @var array
         */
        protected $casOptions;
    
        /**
         * @var phpCAS
         */
        protected $casClient;
    
        /**
         * @var LdapPeopleMapper
         */
        protected $ldapPeopleMapper;
    
        /**
         * Réalise l'authentification.
         *
         * @param AuthEvent $e
         * @return boolean
         * @throws UnexpectedValueException
         * @see ChainableAdapter
         */
        public function authenticate(AuthEvent $e)
        {
    //        if ($e->getIdentity()) {
    //            return;
    //        }
    	/* DS : modification liée à une boucle infinie lors de l'authentification CAS */
    	if ($this->isSatisfied()) {
                $storage = $this->getStorage()->read();
                $e->setIdentity($storage['identity'])
                        ->setCode(AuthenticationResult::SUCCESS)
                        ->setMessages(['Authentication successful.']);
                return;
            }
    
            $config = $this->getOptions()->getCas();
            if (!$config) {
                return; // NB: l'authentification CAS est désactivée ssi le tableau des options est vide
            }
    
            error_reporting($oldErrorReporting = error_reporting() & ~E_NOTICE);
    
            $this->getCasClient()->forceAuthentication();
    
            // at this step, the user has been authenticated by the CAS server
            // and the user's login name can be read with phpCAS::getUser().
    
            $identity = $this->getCasClient(false)->getUser();
    
            error_reporting($oldErrorReporting);
    
            $e->setIdentity($identity);
            $this->setSatisfied(true);
            $storage = $this->getStorage()->read();
            $storage['identity'] = $e->getIdentity();
            $this->getStorage()->write($storage);
            $e->setCode(AuthenticationResult::SUCCESS)
              ->setMessages(['Authentication successful.']);
    
            // recherche de l'individu dans l'annuaire LDAP (il existe forcément puisque l'auth CAS a réussi)
            $ldapPeople = $this->getLdapPeopleMapper()->findOneByUsername($identity);
    
            /* @var $userService User */
            $userService = $this->serviceLocator->get('unicaen-auth_user_service');
            $userService->userAuthenticated($ldapPeople);
        }
    
        /**
         *
         * @param AuthEvent $e
         * @see ChainableAdapter
         */
        public function logout(AuthEvent $e)
        {
            if (!$this->getOptions()->getCas()) {
                return; // NB: l'authentification CAS est désactivée ssi le tableau des options est vide
            }
    
            $router = $this->serviceLocator->get('router'); /* @var $router TreeRouteStack */
            $returnUrl = $router->getRequestUri()->setPath($router->getBaseUrl())->toString();
            $this->getCasClient()->logoutWithRedirectService($returnUrl);
        }
    
        /**
         * Retourne le client CAS.
         *
         * @param boolean $initClient
         * @return phpCAS
         * @throws Exception
         */
        public function getCasClient($initClient = true)
        {
            if (null === $this->casClient) {
                $this->casClient = new phpCAS();
            }
    
            if (!$initClient) {
                return $this->casClient;
            }
    
            if (null === $this->casOptions) {
                $config = $this->getOptions()->getCas();
                if (!isset($config['connection']['default']['params']) || !$config['connection']['default']['params']) {
                    throw new Exception("Les paramètres de connexion au serveur CAS sont invalides.");
                }
                $this->casOptions = $config['connection']['default']['params'];
            }
    
            $options = $this->casOptions;
    
            if (array_key_exists('debug', $options) && (bool) $options['debug']) {
                $this->casClient->setDebug();
            }
    
            // initialize phpCAS
            $this->casClient->client($options['version'], $options['hostname'], $options['port'], $options['uri'], true);
            // no SSL validation for the CAS server
            $this->casClient->setNoCasServerValidation();
    
            return $this->casClient;
        }
    
        /**
         * Spécifie le client CAS.
         *
         * @param phpCAS $casClient
         * @return self
         */
        public function setCasClient(phpCAS $casClient)
        {
            $this->casClient = $casClient;
            return $this;
        }
    
        /**
         * @param ModuleOptions $options
         */
        public function setOptions(ModuleOptions $options)
        {
            $this->options = $options;
        }
    
        /**
         * @return ModuleOptions
         */
        public function getOptions()
        {
            if (!$this->options instanceof ModuleOptions) {
                $options = array_merge(
                        $this->serviceLocator->get('zfcuser_module_options')->toArray(),
                        $this->serviceLocator->get('unicaen-auth_module_options')->toArray());
                $this->setOptions(new ModuleOptions($options));
            }
            return $this->options;
        }
    
        /**
         * get ldap people mapper
         *
         * @return LdapPeopleMapper
         */
        public function getLdapPeopleMapper()
        {
            if (null === $this->ldapPeopleMapper) {
                $this->ldapPeopleMapper = $this->serviceLocator->get('ldap_people_mapper');
            }
            return $this->ldapPeopleMapper;
        }
    
        /**
         * set ldap people mapper
         *
         * @param LdapPeopleMapper $mapper
         * @return self
         */
        public function setLdapPeopleMapper(LdapPeopleMapper $mapper)
        {
            $this->ldapPeopleMapper = $mapper;
            return $this;
        }
    
        /**
         * Retrieve EventManager instance
         *
         * @return EventManagerInterface
         */
        public function getEventManager()
        {
            return $this->eventManager;
        }
    
        /**
         * {@inheritdoc}
         */
        public function setEventManager(EventManagerInterface $eventManager)
        {
            $this->eventManager = $eventManager;
            return $this;
        }
    
        /**
         * @param TreeRouteStack $router
         */
        public function reconfigureRoutesForCasAuth(TreeRouteStack $router)
        {
            $router->addRoutes([
                // remplace les routes existantes (cf. config du module)
                'zfcuser' => [
                    'type'          => 'Literal',
                    'priority'      => 1000,
                    'options'       => [
                        'route'    => '/auth',
                        'defaults' => [
                            'controller' => 'zfcuser',
                            'action'     => 'index',
                        ],
                    ],
                    'may_terminate' => true,
                    'child_routes'  => [
                        'login'  => [
                            'type'    => 'Literal',
                            'options' => [
                                'route'    => '/connexion',
                                'defaults' => [
                                    'controller' => 'zfcuser',
                                    'action'     => 'authenticate', // zappe l'action 'login'
                                ],
                            ],
                        ],
                        'logout' => [
                            'type'    => 'Literal',
                            'options' => [
                                'route'    => '/deconnexion',
                                'defaults' => [
                                    'controller' => 'zfcuser',
                                    'action'     => 'logout',
                                ],
                            ],
                        ],
                    ],
                ],
            ]);
        }
    }