Commit fb477fb9 authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

Work in progress

parent e3e9cf98
......@@ -2,9 +2,19 @@
namespace UnicaenAuth;
use UnicaenAuth\Authentication\Adapter\Cas as CasAdapter;
use UnicaenAuth\Options\ModuleOptions;
use UnicaenAuth\Service\ShibService;
use Zend\EventManager\EventInterface;
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
use Zend\ModuleManager\Feature\ServiceProviderInterface;
use Zend\Mvc\Router\Http\TreeRouteStack;
use Zend\ServiceManager\Exception\ServiceNotFoundException;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\View\Helper\Navigation;
use ZfcUser\Form\Login;
use ZfcUser\Form\LoginFilter;
/**
* Point d'entrée du module d'authentification Unicaen.
......@@ -14,7 +24,11 @@ use Zend\ModuleManager\Feature\ServiceProviderInterface;
class Module implements AutoloaderProviderInterface, ConfigProviderInterface, ServiceProviderInterface
{
/**
*
* @var ModuleOptions
*/
private $options;
/**
* @return array
* @see ConfigProviderInterface
*/
......@@ -23,10 +37,7 @@ class Module implements AutoloaderProviderInterface, ConfigProviderInterface, Se
return include __DIR__ . '/config/module.config.php';
}
/**
*
* @return array
* @see AutoloaderProviderInterface
*/
......@@ -44,8 +55,6 @@ class Module implements AutoloaderProviderInterface, ConfigProviderInterface, Se
];
}
/**
* This method is called once the MVC bootstrapping is complete,
* after the "loadModule.post" event, once $application->bootstrap() is called.
......@@ -54,9 +63,9 @@ class Module implements AutoloaderProviderInterface, ConfigProviderInterface, Se
*
* @see BootstrapListenerInterface
*/
public function onBootstrap(\Zend\EventManager\EventInterface $e)
/* @var \Zend\Mvc\MvcEvent $e */
public function onBootstrap(EventInterface $e)
{
/* @var \Zend\Mvc\MvcEvent $e */
$application = $e->getApplication();
/* @var $services \Zend\ServiceManager\ServiceManager */
$services = $application->getServiceManager();
......@@ -65,63 +74,45 @@ class Module implements AutoloaderProviderInterface, ConfigProviderInterface, Se
try {
$authorizeService = $services->get('BjyAuthorize\Service\Authorize');
/* @var $authorizeService \BjyAuthorize\Service\Authorize */
\Zend\View\Helper\Navigation::setDefaultAcl($authorizeService->getAcl());
\Zend\View\Helper\Navigation::setDefaultRole($authorizeService->getIdentity());
} catch (\Zend\ServiceManager\Exception\ServiceNotFoundException $snfe) {
Navigation::setDefaultAcl($authorizeService->getAcl());
Navigation::setDefaultRole($authorizeService->getIdentity());
} catch (ServiceNotFoundException $snfe) {
// pas de module BjyAuthorize : pas d'ACL
}
/* @var $options Options\ModuleOptions */
$options = $services->get('unicaen-auth_module_options');
/* @var $options ModuleOptions */
$this->options = $services->get('unicaen-auth_module_options');
// si l'auth CAS est demandée, modif de la route de connexion pour zapper le formulaire
if ($options->getCas() && php_sapi_name() !== 'cli') {
/* @var $router \Zend\Mvc\Router\Http\TreeRouteStack */
$router = $services->get('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',
],
],
],
],
],
]);
}
$this->reconfigureRoutesForAuth($services);
}
/**
* @param ServiceLocatorInterface $sl
*/
private function reconfigureRoutesForAuth(ServiceLocatorInterface $sl)
{
/* @var $router \Zend\Mvc\Router\Http\TreeRouteStack */
$router = $sl->get('router');
// si l'auth CAS est activée, modif de la route de connexion pour zapper le formulaire d'auth maison.
$isCasEnable = (bool) $this->options->getCas();
if ($isCasEnable && php_sapi_name() !== 'cli') {
/** @var CasAdapter $casAdapter */
$casAdapter = $sl->get('UnicaenAuth\Authentication\Adapter\Cas');
$casAdapter->reconfigureRoutesForCasAuth($router);
}
// si l'auth Shibboleth est activée, modif de la route de déconnexion pour réaliser la déconnexion Shibboleth.
$shibOptions = $this->options->getShibboleth();
$isShibEnable = array_key_exists('enable', $shibOptions) && (bool) $shibOptions['enable'];
if ($isShibEnable && php_sapi_name() !== 'cli') {
/** @var ShibService $shibService */
$shibService = $sl->get(ShibService::class);
$shibService->reconfigureRoutesForShibAuth($router);
}
}
/**
*
* @return array
* @see ServiceProviderInterface
*/
......@@ -132,8 +123,8 @@ 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 \ZfcUser\Form\Login(null, $options);
$form->setInputFilter(new \ZfcUser\Form\LoginFilter($options));
$form = new Login(null, $options);
$form->setInputFilter(new LoginFilter($options));
$form->get('identity')->setLabel("Username");
return $form;
......
......@@ -9,6 +9,7 @@ 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\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;
use ZfcUser\Authentication\Adapter\AbstractAdapter;
......@@ -230,4 +231,48 @@ class Cas extends AbstractAdapter implements ServiceManagerAwareInterface, Event
$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',
],
],
],
],
],
]);
}
}
\ No newline at end of file
......@@ -9,10 +9,12 @@ use Zend\Authentication\AuthenticationService;
use Zend\Authentication\Exception\ExceptionInterface;
use Zend\Http\Response;
use Zend\Mvc\Controller\AbstractActionController;
use ZfcUser\Controller\Plugin\ZfcUserAuthentication;
/**
* Classe ajoutée lors de l'implémentation de l'auth Shibboleth.
*
* @method ZfcUserAuthentication zfcUserAuthentication()
* @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
*/
class AuthController extends AbstractActionController
......@@ -25,10 +27,28 @@ class AuthController extends AbstractActionController
*/
public function shibbolethAction()
{
$operation = $this->params()->fromRoute('operation');
if ($operation === 'deconnexion') {
// déconnexion applicative quoiqu'il arrive
$this->zfcUserAuthentication()->getAuthAdapter()->resetAdapters();
$this->zfcUserAuthentication()->getAuthAdapter()->logoutAdapters();
$this->zfcUserAuthentication()->getAuthService()->clearIdentity();
// déconnexion Shibboleth le cas échéant
if ($this->shibService->isShibbolethEnable()) {
$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
}
}
$shibUser = $this->shibService->getAuthenticatedUser();
if ($shibUser === null) {
return []; // la page d'aide s'affiche
return []; // une page d'aide s'affichera
}
/** @var AuthenticationService $authService */
......@@ -45,4 +65,9 @@ class AuthController extends AbstractActionController
return $this->redirect()->toUrl($redirectUrl);
}
public function shibboleth()
{
}
}
\ No newline at end of file
......@@ -5,6 +5,7 @@ namespace UnicaenAuth\Service;
use UnicaenApp\Exception\RuntimeException;
use UnicaenAuth\Entity\Shibboleth\ShibUser;
use UnicaenAuth\Options\ModuleOptions;
use Zend\Mvc\Router\Http\TreeRouteStack;
/**
* Shibboleth service
......@@ -102,6 +103,23 @@ EOS;
return $shibUser;
}
/**
* Retourne l'URL de déconnexion Shibboleth.
*
* @param string $returnAbsoluteUrl Eventuelle URL *absolue* de retour après déconnexion
* @return string
*/
public function getLogoutUrl($returnAbsoluteUrl = null)
{
$logoutRelativeUrl = '/Shibboleth.sso/Logout?return='; // NB: '?return=' semble obligatoire!
if ($returnAbsoluteUrl) {
$logoutRelativeUrl .= urlencode($returnAbsoluteUrl);
}
return $logoutRelativeUrl;
}
/**
* @param ModuleOptions $options
*/
......@@ -109,4 +127,49 @@ EOS;
{
$this->options = $options;
}
/**
* @param TreeRouteStack $router
*/
public function reconfigureRoutesForShibAuth(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', // NB: lorsque l'auth Shibboleth est activée, la page propose
'action' => 'login', // 2 possibilités d'auth : LDAP et Shibboleth.
],
],
],
'logout' => [
'type' => 'Segment',
'options' => [
'route' => '/:operation/shibboleth/',
'defaults' => [
'controller' => 'UnicaenAuth\Controller\Auth',
'action' => 'shibboleth',
'operation' => 'deconnexion'
],
],
],
],
],
]);
}
}
\ No newline at end of file
......@@ -41,7 +41,8 @@ class ShibConnectViewHelper extends AbstractHelper
$shibUrl = $this->getView()->url('auth/shibboleth', [], ['query' => $this->getView()->queryParams()], true);
return <<<EOS
<a href="$shibUrl" class="btn btn-info btn-lg">Se connecter via la fédération d'identité</a>
Se connecter plutôt avec la
<a href="$shibUrl" class="btn btn-success btn-lg">Fédération d'identité Renater</a>
EOS;
}
}
\ No newline at end of file
......@@ -11,51 +11,61 @@ $form->setAttributes([
?>
<style>
#div-connexion { max-width: 350px; margin: auto; }
.div-connexion { max-width: 350px; margin: auto auto 30px; }
.div-connexion h2 { margin: 0; }
.div-connexion .btn-primary { margin: 10px 0; }
.div-connexion .btn-success { margin: 10px 0; display: inline-block; }
</style>
<div id="div-connexion">
<div class="div-connexion panel panel-primary">
<h1 class="page-header"><?php echo $this->translate("Connexion"); ?></h1>
<div class="panel-heading">
<h2><?php echo $this->translate("Connexion"); ?></h2>
</div>
<?php echo $this->form()->openTag($form) ?>
<div class="panel-body">
<?php echo $this->form()->openTag($form) ?>
<?php if (($errors = $this->formErrors($this->loginForm))): ?>
<p><?php echo $errors ?></p>
<?php endif ?>
<p>
<?php
$identity = $form->get($name = 'identity')->setAttributes(['id' => $name, 'class' => 'form-control']);
echo $this->formLabel($identity);
echo $this->formInput($identity);
?>
</p>
<p>
<?php
$identity = $form->get($name = 'credential')->setAttributes(['id' => $name, 'class' => 'form-control']);
echo $this->formLabel($identity);
echo $this->formInput($identity);
?>
</p>
<?php if ($this->redirect): ?>
<input type="hidden" name="redirect" value="<?php echo $this->redirect ?>" />
<?php endif ?>
<p>
<?php echo $this->formButton($form->get('submit')->setAttribute('class', 'btn btn-primary')) ?>
</p>
<?php echo $this->form()->closeTag() ?>
<?php if (($errors = $this->formErrors($this->loginForm))): ?>
<p><?php echo $errors ?></p>
<?php endif ?>
<hr>
<p>
<?php
$identity = $form->get($name = 'identity')->setAttributes(['id' => $name, 'class' => 'form-control']);
echo $this->formLabel($identity);
echo $this->formInput($identity);
?>
</p>
<p>
<?php
$identity = $form->get($name = 'credential')->setAttributes(['id' => $name, 'class' => 'form-control']);
echo $this->formLabel($identity);
echo $this->formInput($identity);
?>
</p>
<?php if ($this->redirect): ?>
<input type="hidden" name="redirect" value="<?php echo $this->redirect ?>" />
<?php endif ?>
<p>
<?php echo $this->formButton($form->get('submit')->setAttribute('class', 'btn btn-primary btn-block')) ?>
</p>
<!-- Connexion Shibboleth (si activée) -->
<?php echo $this->shibConnect() ?>
</div>
</div>
<?php echo $this->form()->closeTag() ?>
<!-- Bouton de connexion Shibboleth -->
<?php echo $this->shibConnect() ?>
<!-- Création d'un compte local (si autorisée) -->
<?php if ($this->enableRegistration) : ?>
<div id="div-connexion" class="panel panel-primary">
<?php echo $this->translate("Not registered?"); ?> <a href="<?php echo $this->url('zfcuser/register') . ($this->redirect ? '?redirect=' . $this->redirect : '') ?>"><?php echo $this->translate("Sign up!"); ?></a>
</div>
<?php endif; ?>
<?php if ($this->enableRegistration) : ?>
<?php echo $this->translate("Not registered?"); ?> <a href="<?php echo $this->url('zfcuser/register') . ($this->redirect ? '?redirect=' . $this->redirect : '') ?>"><?php echo $this->translate("Sign up!"); ?></a>
<?php endif; ?>
</div>
<script type="text/javascript">
// focus sur le 1er champ vide
$("input").filter(function() {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment