FOSUserBundle - how to redirect already registered users when trying to access login_path

Is it possible to automatically redirect to a route (i.e. /) for a specific route /loginonly for users AUTHENTICATED? And How?

I am using FOSUserBundle.

This is my security configuration:

security:
    encoders:
        FOS\UserBundle\Model\UserInterface: sha512

role_hierarchy:
    ROLE_ADMIN:       ROLE_USER
    ROLE_SUPER_ADMIN: ROLE_ADMIN

providers:
    fos_userbundle:
        id: fos_user.user_provider.username_email

firewalls:
    main:
        pattern: ^/
        form_login:
            provider: fos_userbundle
            csrf_provider: form.csrf_provider
            login_path: /accedi
            check_path: /login_check
            default_target_path: /
        oauth:
            resource_owners:
                facebook:           "/login/check-facebook"
                google:             "/login/check-google"
            login_path:        /accedi
            failure_path:      /accedi
            default_target_path: /

            oauth_user_provider:
                service: my_user_provider
        logout:
            path: /logout
            target: /
            invalidate_session: false
        anonymous:  ~
    login:
        pattern:  ^/login$
        security: false

        remember_me:
            key: "%secret%"
            lifetime: 31536000 # 365 days in seconds
            path: /
            domain: ~ 

    oauth_authorize:
        pattern:    ^/oauth/v2/auth
        form_login:
            provider: fos_userbundle
            check_path: _security_check
            login_path: _demo_login
        anonymous: true

    oauth_token:
        pattern:    ^/oauth/v2/token
        security:   false


access_control:
    - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/accedi$, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/registrati, role: IS_AUTHENTICATED_ANONYMOUSLY }
+4
source share
5 answers

Since you are using FOSUserBundle, the rendering of the login form happens in . SecurityController::renderLogin()

The decision is based on:

  • override SecurityController
  • adding validation for a role IS_AUTHENTICATD_ANONYMOUSLY
  • redirect the user to another page if the role is not found

, , FOSUserBundle, User Entity.

, YourUserBundle src/Your/Bundle/UserBundle.

( ) SecurityController

vendor/friendsofsymfony/user-bundle/src/FOS/UserBundle/Controller/SecurityController.php

to ( , FOSUserBundle)

src/Your/Bundle/UserBundle/Controller/SecurityController.php

use RedirectResponse renderLogin() :

use Symfony\Component\HttpFoundation\RedirectResponse;

// ...

protected function renderLogin(array $data)
{
    if (false === $this->container->get('security.context')->isGranted('IS_AUTHENTICATED_ANONYMOUSLY')) {
        return new RedirectResponse('/', 403);
    }

    $template = sprintf('FOSUserBundle:Security:login.html.%s', $this->container->getParameter('fos_user.template.engine'));

    return $this->container->get('templating')->renderResponse($template, $data);
}

Update

security.context security.authorization_checker.

http://symfony.com/blog/new-in-symfony-2-6-security-component-improvements

+10

, . . . , .

. , .

Security Controller. , MyUserBundle MyProject, FOSUserBundle.

<?php

namespace MyProject\MyUserBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use FOS\UserBundle\Controller\SecurityController as BaseSecurityController;

class SecurityController extends BaseSecurityController
{

    /**
     * Overriding login to add custom logic.
     */
    public function loginAction(Request $request)
    {
        if( $this->container->get('security.context')->isGranted('IS_AUTHENTICATED_REMEMBERED') ){

            // IS_AUTHENTICATED_FULLY also implies IS_AUTHENTICATED_REMEMBERED, but IS_AUTHENTICATED_ANONYMOUSLY doesn't

            return new RedirectResponse($this->container->get('router')->generate('some_route_name_in_my_project', array())); 
            // of course you don't have to use the router to generate a route if you want to hard code a route
        }

        return parent::loginAction($request);
    }
}
+7

NB: Symfony 3.0.4@dev

, @nifr @mirk @Ronan.

, SecurityController :

<?php

namespace AppBundle\Controller;

use Symfony\Component\HttpFoundation\RedirectResponse;
use FOS\UserBundle\Controller\SecurityController as BaseController;

class SecurityController extends BaseController
{

    /**
     * Renders the login template with the given parameters. Overwrite this function in
     * an extended controller to provide additional data for the login template.
     *
     * @param array $data
     *
     * @return \Symfony\Component\HttpFoundation\Response
     */
    protected function renderLogin (array $data)
    {
        // This little if do the trick
        if ($this->container->get('security.authorization_checker')->isGranted('ROLE_USER')) {
            return new RedirectResponse($this->container->get ('router')->generate ('app_generation_page'));
        }

        $template = sprintf ('FOSUserBundle:Security:login.html.twig');
        return $this->container->get ('templating')->renderResponse ($template, $data);
    }
}

RegistrationController, .

, .

+2

, @nifr. renderLogin . . Bundle

namespace MyProject\UserBundle\Controller;
//namespace FOS\UserBundle\Controller;

 use Symfony\Component\HttpFoundation\RedirectResponse;
 use \FOS\UserBundle\Controller\SecurityController as BaseController;

 class SecurityController extends BaseController {

/**
 * Renders the login template with the given parameters. Overwrite this function in
 * an extended controller to provide additional data for the login template.
 *
 * @param array $data
 *
 * @return \Symfony\Component\HttpFoundation\Response
 */
  protected function renderLogin(array $data) {

    if (true === $this->container->get('security.context')->isGranted('ROLE_USER')) {
        return new RedirectResponse($this->container->get('router')-  >generate('homeroute'));
    }

    $template = sprintf('FOSUserBundle:Security:login.html.%s', $this->container->getParameter('fos_user.template.engine'));

    return $this->container->get('templating')->renderResponse($template, $data);
  }

}  
+1

I use routing and security to enable this.

#routing.yml
index:
    path: /
    defaults: { _controller: AppBundle:Base:index }
    methods: [GET]

login:
    path: /login
    defaults: { _controller: AppBundle:Security:login }
    methods: [GET]

If the user is logged in, he is redirected to the control panel. If not, he will see the login route.

#security.yml
    access_control:
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/dashboard, role: ROLE_USER }

Hope this helps you. :)

-1
source

All Articles