Forráskód Böngészése

[Security] adds logout success handler

Johannes Schmitt 14 éve
szülő
commit
b685b3ab4d

+ 1 - 0
src/Symfony/Bundle/SecurityBundle/DependencyInjection/Configuration.php

@@ -141,6 +141,7 @@ class Configuration
                         ->canBeUnset()
                         ->scalarNode('path')->defaultValue('/logout')->end()
                         ->scalarNode('target')->defaultValue('/')->end()
+                        ->scalarNode('success_handler')->end()
                         ->booleanNode('invalidate_session')->defaultTrue()->end()
                         ->fixXmlConfig('delete_cookie')
                         ->arrayNode('delete_cookies')

+ 7 - 2
src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php

@@ -243,10 +243,15 @@ class SecurityExtension extends Extension
         if (isset($firewall['logout'])) {
             $listenerId = 'security.logout_listener.'.$id;
             $listener = $container->setDefinition($listenerId, new DefinitionDecorator('security.logout_listener'));
-            $listener->addArgument($firewall['logout']['path']);
-            $listener->addArgument($firewall['logout']['target']);
+            $listener->setArgument(1, $firewall['logout']['path']);
+            $listener->setArgument(2, $firewall['logout']['target']);
             $listeners[] = new Reference($listenerId);
 
+            // add logout success handler
+            if (isset($firewall['logout']['success_handler'])) {
+                $listener->setArgument(3, new Reference($firewall['logout']['success_handler']));
+            }
+
             // add session logout handler
             if (true === $firewall['logout']['invalidate_session'] && false === $firewall['stateless']) {
                 $listener->addMethodCall('addHandler', array(new Reference('security.logout.handler.session')));

+ 3 - 0
src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml

@@ -84,6 +84,9 @@
 
         <service id="security.logout_listener" class="%security.logout_listener.class%" public="false" abstract="true">
             <argument type="service" id="security.context" />
+            <argument /> <!-- Logout Path -->
+            <argument /> <!-- Target-URL Path -->
+            <argument type="service" id="security.logout.success_handler" on-invalid="null" />
         </service>
         <service id="security.logout.handler.session" class="%security.logout.handler.session.class%" public="false" />
         <service id="security.logout.handler.cookie_clearing" class="%security.logout.handler.cookie_clearing.class%" public="false" abstract="true" />

+ 0 - 2
src/Symfony/Bundle/SecurityBundle/SecurityBundle.php

@@ -13,7 +13,6 @@ namespace Symfony\Bundle\SecurityBundle;
 
 use Symfony\Component\HttpKernel\Bundle\Bundle;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
-use Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\AddAuthenticationProvidersPass;
 use Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\AddSecurityVotersPass;
 
 /**
@@ -28,6 +27,5 @@ class SecurityBundle extends Bundle
         parent::registerExtensions($container);
 
         $container->addCompilerPass(new AddSecurityVotersPass());
-        $container->addCompilerPass(new AddAuthenticationProvidersPass());
     }
 }

+ 15 - 3
src/Symfony/Component/Security/Http/Firewall/LogoutListener.php

@@ -11,6 +11,8 @@
 
 namespace Symfony\Component\Security\Http\Firewall;
 
+use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
+
 use Symfony\Component\Security\Http\Logout\LogoutHandlerInterface;
 use Symfony\Component\Security\Core\SecurityContextInterface;
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
@@ -28,6 +30,7 @@ class LogoutListener implements ListenerInterface
     protected $logoutPath;
     protected $targetUrl;
     protected $handlers;
+    protected $successHandler;
 
     /**
      * Constructor
@@ -36,11 +39,12 @@ class LogoutListener implements ListenerInterface
      * @param string $logoutPath The path that starts the logout process
      * @param string $targetUrl  The URL to redirect to after logout
      */
-    public function __construct(SecurityContextInterface $securityContext, $logoutPath, $targetUrl = '/')
+    public function __construct(SecurityContextInterface $securityContext, $logoutPath, $targetUrl = '/', LogoutSuccessHandlerInterface $successHandler = null)
     {
         $this->securityContext = $securityContext;
         $this->logoutPath = $logoutPath;
         $this->targetUrl = $targetUrl;
+        $this->successHandler = $successHandler;
         $this->handlers = array();
     }
 
@@ -86,8 +90,16 @@ class LogoutListener implements ListenerInterface
             return;
         }
 
-        $response = new Response();
-        $response->setRedirect(0 !== strpos($this->targetUrl, 'http') ? $request->getUriForPath($this->targetUrl) : $this->targetUrl, 302);
+        if (null !== $this->successHandler) {
+            $response = $this->successHandler->onLogoutSuccess($event, $request);
+
+            if (!$response instanceof Response) {
+                throw new \RuntimeException('Logout Success Handler did not return a Response.');
+            }
+        } else {
+            $response = new Response();
+            $response->setRedirect(0 !== strpos($this->targetUrl, 'http') ? $request->getUriForPath($this->targetUrl) : $this->targetUrl, 302);
+        }
 
         // handle multiple logout attempts gracefully
         if ($token = $this->securityContext->getToken()) {

+ 29 - 0
src/Symfony/Component/Security/Http/Logout/LogoutSuccessHandlerInterface.php

@@ -0,0 +1,29 @@
+<?php
+
+namespace Symfony\Component\Security\Http\Logout;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\EventDispatcher\EventInterface;
+
+/**
+ * LogoutSuccesshandlerInterface.
+ *
+ * In contrast to the LogoutHandlerInterface, this interface can return a response
+ * which is then used instead of the default behavior.
+ *
+ * If you want to only perform some logout related clean-up task, use the
+ * LogoutHandlerInterface instead.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+interface LogoutSuccessHandlerInterface
+{
+    /**
+     * Creates a Response object to send upon a successful logout.
+     *
+     * @param EventInterface $event
+     * @param Request $request
+     * @return Response never null
+     */
+    function onLogoutSuccess(EventInterface $event, Request $request);
+}