Symfony2: Check user authentication based on path

authentication, php, symfony

Solution

The `security.access_map` service

The configuration of security.access_control is processed by ...

SecurityBundle\DependencyInjection\SecurityExtension

... which creates RequestMatchers for the routes (path,hosts,ip,...) and then invokes the service's `add()` method with the matcher, the allowed roles and the channel (i.e. https ).

The service is usually used by i.e. the AccessListener.

You can use the security.access_map service to access the security.access_control parameters in your application.

The class used for the security.access_map service is defined by the parameter security.access_map.class and defaults to

`Symfony\Component\Security\Http\AccessMap` ( implements AccessMapInterface )

You can use the parameter security.access_map.class to override the service with a custom class (must implement AccessMapInterface):

# i.e. app/config/config.yml

parameters:
    security.access_map.class: My\Custom\AccessMap

How to access the service

The `security.access_map` service is a private service as you can see by it's definition here.

This means you can't request it from the container directly like this:

`$this->container->get('security.access_map')`

You will have to inject it into another service (i.e. a listener service) explicitly to be able to access it.

A listener example

services:
    my_listener:
        class: My\Bundle\MyListenerBundle\EventListener\ForbiddenRouteListener
        arguments: [ @security.access_map ]
        tags:      
            - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }

Then you can call the `getPatterns()` method to obtain the RequestMatchers, allowed roles and required channel from there.

namespace My\Bundle\MyListenerBundle\EventListener;

use Symfony\Component\Security\Http\AccessMapInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;

class ForbiddenRouteListener
{

    protected $accessMap;

    public function __construct(AccessMapInterface $access_map)
    {
        $this->accessMap = $access_map;
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        $request = $event->getRequest();
        $patterns = $this->accessMap->getPatterns($request);

        // ...

Problem

in Symfony2, is it possible to check if user is authenticated to access the URl he requested. What I want to do is, i dont want to allow a logged in user to go back to registration or login or recover password pages. here is my security.yml: ``` access_control: - { path: ^/signup/, roles: IS_AUTHENTICATED_ANONYMOUSLY && !IS_AUTHENTICATED_FULLY} - { path: ^/register/, roles: IS_AUTHENTICATED_ANONYMOUSLY && !IS_AUTHENTICATED_FULLY} - { path: ^/recover/, roles: IS_AUTHENTICATED_ANONYMOUSLY && !IS_AUTHENTICATED_FULLY} ``` but this is showing, access denied page to current user. So i think it would be nice if I can redirect the user to home page on such request, by checking if he is not allowed. Can I check by providing path that user is authenticated or not in listener? ``` public function onKernelResponse(FilterResponseEvent $event) { $request = $event->getRequest(); $path = $request->getPathInfo(); if($this->container->get('security.context')->getToken() != null) { // To check if user is authenticated or anonymous if( ($this->container->get('security.context')->getToken() instanceof UsernamePasswordToken) && ($this->container->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY') == true) ) { // HOW TO CHECK PATH ? // set response to redirect to home page } } } ```

Original source