New in Symfony 4.4: Lazy Firewalls

Contributed by
Nicolas Grekas
in #33676.

In Symfony's Security component, firewalls configure how your users will be able to authenticate (e.g. using a login form, an API token, etc). Firewalls also configure which URLs they cover and whether anonymous users are allowed to browse those URLs or not:

1
2
3
4
5
6
7
8
# config/packages/security.yaml
security:
    # ...
    firewalls:
        main:
            pattern: ^/
            anonymous: ~
            # ...

When a stateful firewall is configured, a user token is always created from the session for every request, no matter if the user is actually used or not by the application. This means that all those responses are uncacheable (because they use the session).

In Symfony 4.4, firewalls can define lazy as the value of their anonymous configuration option:

1
2
3
4
5
6
7
8
# config/packages/security.yaml
security:
    # ...
    firewalls:
        main:
            pattern: ^/
            anonymous: lazy
            # ...

This tells Symfony to only load the user (and start the session) if the application actually access the user object (e.g. via a is_granted() call in a template or a isGranted() call in a controller or service). This means that all those URLs/actions that don't need the user will now be public and cacheable, improving the performance of your application.

Comments

Wonderful news!!
Alas, I'm still using FOSUserBundle, and when adding lazy to the configuration, I get "RuntimeException: You must configure the check path to be handled by the firewall using form_login in your security firewall configuration.

# security.yaml

auth:
pattern: ^/
form_login:
provider: fos_userbundle
login_path: fos_user_security_login
check_path: fos_user_security_check
# csrf_token_generator: security.csrf.token_manager
remember_me:
secret: '%kernel.secret%'
lifetime: 604800 # 1 week in seconds
path: /
samesite: lax
logout: true
anonymous: lazy
Great news indeed! Do you reckon it will need special configuration when using FOSHttpCacheBundle (in order to maximize the sharing of cached responses between requests coming in from different logged-in users)?
Awesome!
Why is this not default? And why is it optional at all? Is there any reason to NOT use it?
@Jáchym: access control being lazy, the check and the auth-exception can happen anywhere in the code flow. That can be a significant behavior change for existing apps, thus the preserved default behavior. Yet, for new apps, lazy is now enabled by default, thanks the recipe provided by flex.
Am i doing something wrong, or enabling lazy prevents rememberMe functionality from working?
I confirm, is that normal?
> enabling lazy prevents rememberMe functionality from working?

Enabling lazy means the rememberMe cookie is not read unless the app accesses the user (via the token storage). If you're testing rememberMe on a page that doesn't access the user, it won't have any effect. Try on a page that reads the user instead (and open an issue with a reproducer if that still doesn't work as expected.)

Comments are closed.

To ensure that comments stay relevant, they are closed for old posts.