Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to make the onAuthenticationSuccess function being called

I would like to have some action after a success authentification.

I created a class extended DefaultAuthenticationSuccessHandler, and redefined the onAuthenticationSuccess function.

Though the authentication is a success, the programm never goes to the function : why ?


namespace my_name_space;

use   Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Bridge\Monolog\Logger;


class AuthenticationSuccessHandler extends DefaultAuthenticationSuccessHandler {
private $em;
private $logger;

function __construct(Logger $logger, HttpUtils $httpUtils, EntityManager $em) {
    parent::__construct($httpUtils);
    $this->em = $em;
    $this->logger = $logger;
}

public function onAuthenticationSuccess(Request $request, TokenInterface $token) {
    $this->logger->info("onAuthenticationSuccess");
    $response = parent::onAuthenticationSuccess($request, $token);
    $token->eraseCredentials();        
    $token->getUser()->addRole('ROLE_USER');

    return $response;
}

}

services:
security.authentication.success.handler:
    class: MY\NAMESPACE\AuthenticationSuccessHandler
    arguments: ["@monolog.logger.php","@security.http_utils", "@doctrine.orm.default_entity_manager"]

security.yml

form_login:
            check_path: _security_check
            use_referer: true
            use_forward: true
            login_path: my_login
            success_handler: security.authentication.success.handler
like image 486
mlwacosmos Avatar asked Feb 26 '16 13:02

mlwacosmos


2 Answers

You can listen for the event that is triggered after a successful login attempt by registering a service to the related security tag:

app.login_listener:
    class: AppBundle\EventListener\LoginListener
    arguments:
        - @security.authorization_checker
        - @security.token_storage
    tags:
        - { name: kernel.event_listener, event: security.interactive_login, method: yourMethod }

Where yourMethod can contain the code you want to execute.

like image 112
Rvanlaak Avatar answered Nov 11 '22 22:11

Rvanlaak


There are a lot of same issues on SO, github, google groups, most of them are unsolved.

Also, you should define a custom AuthenticationSuccessHandler rather than extending the default.

Example:

services.yml

login_success_handler:
    class:  YourBundle\EventListener\CustomAuthenticationSuccessHandler
    arguments:  ["@doctrine", "@router"]
    tags:
        - { name: kernel.event_listener, event: security.interactive_login, method: onSecurityInteractiveLogin }

CustomAuthenticationSuccessHandler.php

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\Routing\RouterInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Doctrine\ORM\EntityManager;

class CustomAuthenticationSuccessHandler {
    private $em;
    private $logger;

    public function __construct(EntityManager $em, RouterInterface $router) 
    {
        $this->em = $em;
        $this->router = $router;
    }

    public function onSecurityInteractiveLogin(InteractiveLoginEvent $event) 
    {
        $this->onAuthenticationSuccess($event->getRequest(), $event->getAuthenticationToken());
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token) 
    {    
        $user = $token->getUser();
        $user->eraseCredentials();        
        $user->addRole('ROLE_USER');

        $this->em->flush() // If you don't do this, your changes will not be saved.
        $response = new RedirectResponse($this->router->generate('your_success_route'));

        return $response;
    }
}

Don't need of manually set the success_handler in your form, because the SuccessHandler is an EventListener and will be used on the corresponding event.

like image 3
chalasr Avatar answered Nov 12 '22 00:11

chalasr