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.
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.
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 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.)