Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit c45ffc4
Showing
12 changed files
with
424 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
composer.lock | ||
vendor/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
namespace L3\Bundle\CasBundle\Controller; | ||
|
||
|
||
use Symfony\Bundle\FrameworkBundle\Controller\Controller; | ||
|
||
class LogoutController extends Controller { | ||
public function logoutAction() { | ||
if(array_key_exists('casLogoutTarget', $this->container->getParameter('cas'))) { | ||
\phpCas::logoutWithRedirectService($this->container->getParameter('cas')['casLogoutTarget']); | ||
} else { | ||
\phpCAS::logout(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<?php | ||
|
||
namespace L3\Bundle\CasBundle\DependencyInjection; | ||
|
||
use Symfony\Component\Config\Definition\Builder\TreeBuilder; | ||
use Symfony\Component\Config\Definition\ConfigurationInterface; | ||
|
||
/** | ||
* This is the class that validates and merges configuration from your app/config files | ||
* | ||
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class} | ||
*/ | ||
class Configuration implements ConfigurationInterface | ||
{ | ||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getConfigTreeBuilder() | ||
{ | ||
$treeBuilder = new TreeBuilder(); | ||
$rootNode = $treeBuilder->root('l3_cas'); | ||
|
||
$rootNode | ||
->children() | ||
->scalarNode('host')->defaultValue(300)->end() | ||
->scalarNode('path')->defaultValue('')->end() | ||
->scalarNode('port')->defaultValue(443)->end() | ||
->scalarNode('ca')->defaultNull()->end() | ||
->booleanNode('handleLogoutRequest')->defaultValue(false)->end() | ||
->scalarNode('casLogoutTarget')->defaultNull()->end() | ||
->booleanNode('force')->defaultValue(true)->end() | ||
->end(); | ||
|
||
return $treeBuilder; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?php | ||
|
||
namespace L3\Bundle\CasBundle\DependencyInjection; | ||
|
||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
use Symfony\Component\Config\FileLocator; | ||
use Symfony\Component\HttpKernel\DependencyInjection\Extension; | ||
use Symfony\Component\DependencyInjection\Loader; | ||
|
||
/** | ||
* This is the class that loads and manages your bundle configuration | ||
* | ||
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html} | ||
*/ | ||
class L3CasExtension extends Extension | ||
{ | ||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function load(array $configs, ContainerBuilder $container) | ||
{ | ||
$configuration = new Configuration(); | ||
$config = $this->processConfiguration($configuration, $configs); | ||
|
||
$container->setParameter('cas', $config); | ||
|
||
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); | ||
$loader->load('services.yml'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?php | ||
|
||
namespace L3\Bundle\CasBundle; | ||
|
||
use L3\Bundle\CasBundle\Security\CasFactory; | ||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
use Symfony\Component\HttpKernel\Bundle\Bundle; | ||
|
||
class L3CasBundle extends Bundle { | ||
public function build(ContainerBuilder $container) { | ||
parent::build($container); | ||
|
||
$extension = $container->getExtension('security'); | ||
$extension->addSecurityListenerFactory(new CasFactory()); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
Bundle CAS for Symfony2. | ||
|
||
Allow wrappe PHPCas with authentication Symfony2. Support the Single Sign Out in contrary of BeSimpleSSoBundle | ||
|
||
Installation of Bundle. | ||
--- | ||
Install the Bundle with add this line in your require in composer.json : | ||
``` | ||
"l3/cas-bundle": "~1.0" | ||
``` | ||
Launch the command **composer update** pour install the package and add the Bundle in AppKernel.php | ||
``` | ||
<?php | ||
// app/AppKernel.php | ||
// ... | ||
class AppKernel extends Kernel | ||
{ | ||
public function registerBundles() | ||
{ | ||
$bundles = array( | ||
// ... | ||
new L3\Bundle\CasBundle\L3CasBundle(), | ||
); | ||
// ... | ||
} | ||
// ... | ||
} | ||
``` | ||
|
||
Configuration of the bundle | ||
--- | ||
In the configuration files (parameters.yml, config.yml, config_prod.yml...), configure your cas server : | ||
``` | ||
l3_cas: | ||
host: cas-test.univ-lille3.fr # Serveur CAS | ||
path: ~ # Chemin de l'application CAS si elle ne se trouve pas à la racine | ||
port: 443 # Port du serveur CAS | ||
ca: false # Définition d'un certificat SSL pour le serveur CAS | ||
handleLogoutRequest: true # Activiation du Single Sign Out (défaut: false) | ||
casLogoutTarget: https://ent-test.univ-lille3.fr # Page de redirection après la déconnexion de l'application | ||
force: false # Permet de checker et non de forcer le CAS, utilisateur : __NO_USER__ si non connecté (Information: Si force désactivé, le Single Sign Out peut ne plus fonctionner). | ||
``` | ||
|
||
Puis configurer le pare-feu : | ||
``` | ||
# app/config/security.yml | ||
security: | ||
providers: | ||
# ... | ||
firewalls: | ||
dev: | ||
pattern: ^/(_(profiler|wdt|error)|css|images|js)/ | ||
security: false | ||
l3_firewall: | ||
pattern: ^/ | ||
security: true | ||
cas: true # Activation du CAS | ||
``` | ||
|
||
Configuration of the Single Sign Out | ||
--- | ||
In order to use the Single Sign Out, it is recommanded to disable the system of the sessions PHP in Symfony2 : | ||
``` | ||
# app/config/config.yml | ||
framework: | ||
# ... | ||
session: | ||
handler_id: ~ | ||
save_path: ~ | ||
``` | ||
**Information :** The bundle check complementary with PHPCas to detect some disconnections requests not fully implemented by PHPCAS (see L3\Bundle\CasBundle\Security\CasListener::checkHandleLogout() for more details) | ||
|
||
UserProvider | ||
--- | ||
For LDAP users, you can use the LdapUserBundle |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
services: | ||
cas.security.authentication.provider: | ||
class: L3\Bundle\CasBundle\Security\CasProvider | ||
arguments: ['', ''] | ||
|
||
cas.security.authentication.listener: | ||
class: L3\Bundle\CasBundle\Security\CasListener | ||
arguments: [@security.context, @security.authentication.manager, %cas%] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<?php | ||
|
||
namespace L3\Bundle\CasBundle\Security; | ||
|
||
|
||
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface; | ||
use Symfony\Component\Config\Definition\Builder\NodeDefinition; | ||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
use Symfony\Component\DependencyInjection\DefinitionDecorator; | ||
use Symfony\Component\DependencyInjection\Reference; | ||
|
||
class CasFactory implements SecurityFactoryInterface { | ||
public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint) { | ||
$providerId = 'security.authentication.provider.cas.'.$id; | ||
$container | ||
->setDefinition($providerId, new DefinitionDecorator('cas.security.authentication.provider')) | ||
->replaceArgument(0, new Reference($userProvider)); | ||
|
||
$listenerId = 'security.authentication.listener.cas.'.$id; | ||
$listener = $container->setDefinition($listenerId, new DefinitionDecorator('cas.security.authentication.listener')); | ||
|
||
return array($providerId, $listenerId, $defaultEntryPoint); | ||
} | ||
|
||
/** | ||
* Defines the position at which the provider is called. | ||
* Possible values: pre_auth, form, http, and remember_me. | ||
* | ||
* @return string | ||
*/ | ||
public function getPosition() { | ||
return 'pre_auth'; | ||
} | ||
|
||
public function getKey() { | ||
return 'cas'; | ||
} | ||
|
||
public function addConfiguration(NodeDefinition $builder) { | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
<?php | ||
|
||
namespace L3\Bundle\CasBundle\Security; | ||
|
||
|
||
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; | ||
use Symfony\Component\HttpFoundation\Response; | ||
use Symfony\Component\HttpKernel\Event\GetResponseEvent; | ||
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; | ||
use Symfony\Component\Security\Core\Exception\AuthenticationException; | ||
use Symfony\Component\Security\Core\SecurityContextInterface; | ||
use Symfony\Component\Security\Http\Firewall\ListenerInterface; | ||
|
||
class CasListener implements ListenerInterface { | ||
protected $securityContext; | ||
protected $authenticationManager; | ||
protected $config; | ||
|
||
public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, $config) { | ||
$this->securityContext = $securityContext; | ||
$this->authenticationManager = $authenticationManager; | ||
$this->config = $config; | ||
} | ||
|
||
public function handle(GetResponseEvent $event) { | ||
if(!isset($_SESSION)) session_start(); | ||
|
||
\phpCAS::setDebug(false); | ||
\phpCas::client(CAS_VERSION_2_0, $this->getParameter('host'), $this->getParameter('port'), is_null($this->getParameter('path')) ? '' : $this->getParameter('path'), true); | ||
if(is_bool($this->getParameter('ca')) && $this->getParameter('ca') == false) { | ||
\phpCAS::setNoCasServerValidation(); | ||
} else { | ||
\phpCAS::setCasServerCACert($this->getParameter('ca')); | ||
} | ||
if($this->getParameter('handleLogoutRequest')) { | ||
if($event->getRequest()->request->has('logoutRequest')) { | ||
$this->checkHandleLogout($event); | ||
} | ||
$logoutRequest = $event->getRequest()->request->get('logoutRequest'); | ||
|
||
\phpCAS::handleLogoutRequests(true); | ||
} else { | ||
\phpCAS::handleLogoutRequests(false); | ||
} | ||
if($this->getParameter('force')) { | ||
\phpCAS::forceAuthentication(); | ||
$force = true; | ||
} else { | ||
$force = false; | ||
if(!isset($_SESSION['cas_user'])) { | ||
$auth = \phpCAS::checkAuthentication(); | ||
if($auth) $_SESSION['cas_user'] = \phpCAS::getUser(); | ||
else $_SESSION['cas_user'] = false; | ||
} | ||
} | ||
|
||
if(!$force) { | ||
if(!$_SESSION['cas_user']) { | ||
$token = new CasToken(array('ROLE_ANON')); | ||
$token->setUser('__NO_USER__'); | ||
} else { | ||
$token = new CasToken(); | ||
$token->setUser($_SESSION['cas_user']); | ||
} | ||
$this->securityContext->setToken($this->authenticationManager->authenticate($token)); | ||
return; | ||
} | ||
|
||
$token = new CasToken(); | ||
$token->setUser(\phpCAS::getUser()); | ||
|
||
try { | ||
$authToken = $this->authenticationManager->authenticate($token); | ||
$this->securityContext->setToken($authToken); | ||
} catch(AuthenticationException $failed) { | ||
$response = new Response(); | ||
$response->setStatusCode(403); | ||
$event->setResponse($response); | ||
} | ||
} | ||
|
||
public function getParameter($key) { | ||
if(!array_key_exists($key, $this->config)) { | ||
throw new InvalidConfigurationException('l3_cas.' . $key . ' is not defined'); | ||
} | ||
return $this->config[$key]; | ||
} | ||
|
||
/** | ||
* Cette fonction sert à vérifier le global logout, PHPCAS n'arrive en effet pas à le gérer étrangement dans Symfony2 | ||
* @param GetResponseEvent $event | ||
*/ | ||
public function checkHandleLogout(GetResponseEvent $event) { | ||
// Récupération du paramètre | ||
$logoutRequest = $event->getRequest()->request->get('logoutRequest'); | ||
// Les chaines recherchés | ||
$open = '<samlp:SessionIndex>'; | ||
$close = '</samlp:SessionIndex>'; | ||
|
||
// Isolation de la clé de session | ||
$begin = strpos($logoutRequest, $open); | ||
$end = strpos($logoutRequest, $close, $begin); | ||
$sessionID = substr($logoutRequest, $begin+strlen($open), $end-strlen($close)-$begin+1); | ||
|
||
// Changement de session et destruction pour forcer l'authentification CAS à la prochaine visite | ||
session_id($sessionID); | ||
session_destroy(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
namespace L3\Bundle\CasBundle\Security; | ||
|
||
|
||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; | ||
use Symfony\Component\Security\Core\User\UserProviderInterface; | ||
use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface; | ||
|
||
class CasProvider implements AuthenticationProviderInterface { | ||
private $userProvider; | ||
private $config; | ||
|
||
public function __construct(UserProviderInterface $userProvider) { | ||
$this->userProvider = $userProvider; | ||
} | ||
|
||
public function authenticate(TokenInterface $token) { | ||
$user = $this->userProvider->loadUserByUsername($token->getUsername()); | ||
|
||
$authenticatedToken = new CasToken($user->getRoles()); | ||
$authenticatedToken->setUser($user); | ||
|
||
|
||
|
||
return $authenticatedToken; | ||
} | ||
|
||
public function supports(TokenInterface $token) { | ||
return $token instanceof CasToken; | ||
} | ||
} |
Oops, something went wrong.