forsberg
forsberg

Reputation: 1913

Get security config in Symfony2?

I'd like to access the security config as it's configured (by default) in security.yml, and in particular actually I need the route name or (even better) generated URL to login. When using FOS User (which I'm using right now) its called "fos_user_security_login" with "/login" URL. I need it to compare with an event's request's (requsted) URL on Kernel's listened events.

I could hardcode this setting check in my Kernel Listener class, like this:

public function onKernelResponse(\Symfony\Component\HttpKernel\Event\FilterResponseEvent $event)
{
    if ($originalResponse->headers->has('location')
        && $originalResponse->headers->get('location') === $router->generate('fos_user_security_login', array(), true))
    {
       //...
    }
}

But what if I changed this setting in future to some another one, e.g. to some "/user/login" path with my custom login handler? This is why I'd like to read the security setting for login.

How can I do this in Symfony?

Upvotes: 1

Views: 503

Answers (1)

dbrumann
dbrumann

Reputation: 17166

If I were you I would refrain from reading the security settings for this as you can have multiple firewalls with multiple logins and your listener would thus have to listen to all of these (which might not be what you want) or artificially restrict to hardcoded firewalls. Also this will tie your implementation to Symfony's security-component, which you should avoid.

An easily reusable approach would be, to add the URL or route name you want to check for as argument to your listener and pass it via Symfony's Service Container and then just compare request with that value:

class LoginListener
{
    /**
     * @var string
     */
    protected $loginUrl;


    /**
     * @param string $loginUrl
     */
    public function __construct($loginUrl)
    {
        // You can even fallback to default if you like:
        if (empty($loginUrl)) {
            $loginUrl = '/login';
        }
        $this->loginUrl = $loginUrl;
    }

    // [...] your comparison just against $this->loginUrl
}

You can then use your bundle's configuration to pass the right argument to that listener.

This way you can easily reuse it outside of Symfony e.g. in Silex without being tied to Symfony's Security-component. Also if you want to check against multiple urls, you can just make it an array and specify the different login urls, e.g. when you have multiple login-mechanisms.

edit: In your bundle's Configuration you can check for parameters and define your fallbacks or an error message or whatever (see Getting and Setting Container Parameters).

edit:

in parameters.yml:

custom_login_path: /my_login

in security.yml:

    main:
        pattern: ^/
        form_login:
            provider: fos_userbundle
            csrf_provider: security.csrf.token_manager # Use form.csrf_provider instead for Symfony <2.4
            login_path: %custom_login_path%

in routing.yml:

fos_user:
    resource: "@FOSUserBundle/Resources/config/routing/all.xml"

# Make sure this follows "fos_user" so it takes precendece over the default
fos_user_security_login:
    path: %custom_login_path%
    defaults: { _controller: FOSUserBundle:Security:login }

in config.yml:

# config for listener in your bundle
my_bundle:
    login_path: %custom_login_path%

Upvotes: 2

Related Questions