The new features of the Symfony Security component from 5.2
(Retrouvez cet article en 🇫🇷 sur le blog de Yousign)
Each new version of Symfony brings a lot of new features. But version 5.1 offers a new authentication system and this system changes the internal behavior of Symfony security, to make it extensible and more understandable.
In this article, I will do an overview of this new system and other new features.
Let’s activate the new system
💡To use the new system, you must first update the security.yaml
like this:
# config/packages/security.yaml
security:
enable_authenticator_manager: true
What is changing? 📚
The authentication workflow is simplified: in the new system, there is only one Listener AuthenticatorManagerListener
who will pass the request to an Authenticator manager AuthenticatorManager
provided by Symfony; then the Authenticator manager will resolve the Authenticators and return a Response.
Here is a diagram taken from an article of Wouter:
Now everything is connected to a single concept and a single interface. The concept is that of Authenticators and the interface is as follows:
⚠️ This interface replaces GuardAuthenticatorInterface
which was introduced in Symfony version 2.8. the getUser
and getCredentials
methods are replaced by a new authenticate
method.
Remember with Guards the getCredentials
method passed the credentials retrieved from an instance of Symfony\Component\HttpFoundation\Request
to the getUser
method, which in turn had to return a UserInterface
to continue the connection workflow.
Now this task is delegated to an authenticate method which should return PassportInterface
💡PassportInterface
is a new concept: a Passport is a class that will contain the information that needs to be validated during the authentication workflow and this information will be transported with a new concept (otherwise it’s not funny), which is the concept of “Badge”, which is used to add information to the passport to extend security.
Suppose we have a Login submitted via a Form, the Authenticator
will look like :
Badges in action 😎
UserBadge
, PasswordCredentials
and CrsfTokenBadge
are badges that must implement a BadgeInterface
.
This interface has one method, isResolved
, and this must return true for all badges for authentication to succeed.
Small explanation on who does what ❓
UserBadge
will resolve the user via a Provider defined in the configuration or a callable that can be passed as the second argument of the constructor. 👤PasswordCredentials
and will check the password. 🔐CrsfTokenBadge
will check that the CRSF token is valid. 🍪Passport
will transport them. ✈️
💝 Here is the code that loops on the badges to confirm authentication:
What’s really handy is that you can add custom badges with your logic in the isResolved
method👌.
A more expandable system ✨
The new AuthenticatorIterface
also modifies the arguments of the createAuthenticatedToken
method. In the Guards system, we had a UserInterface
and firewall in the settings. It was therefore very difficult to add custom information to the created Token.
In the new system, we get the PassportInterface
returned in the authenticate
method, so there is a lot more context to create our token 🎉
🔥 If you do not have specific needs, it is unnecessary to create an Authenticator, Symfony provides many authenticators:
To use them, you just have to declare which one you want:
# security.yaml
# other stufffirewalls:
main:
form_login: ~ # FormLoginAuthenticator
# OR
http_basic: ~ # HttpBasicAuthenticato
🌠 Let’s go to version 5.2 (date of this article) to identify other new features. Here is a non-exhaustive list:
- Many Events 🎁 (CheckPassportEvent, LoginSuccessEvent , LogoutEvent, SwitchUserEvent…)
- End of Anonymous User : the user is authenticated or not, if not there is no token in “security”
- New keyword
PUBLIC_ACCESS
in the access control ofsecurity.yaml
to allows non authenticated users, like instructionIS_AUTHENTICATED_ANONYMOUSLY
- Login Throttling to limit the number of connection attempts
- Login Link (passwordless) to authenticate a user via a link (by email, etc.)
- Grant access to unauthenticated users in a Voter Custom
These are the big news that I was able to identify. 😎
Thanks for reading me, don’t hesitate to clap the max 👏👏👏
Share the article if you liked it.
Sources: To write this article I relied on the documentation, an article by Wouter, and slides of the presentation made by Ryan Weaver at SFCon 2020, the best documentation is the code so I explored these new features myself by opening the vendor with ctrl + enter
🔦.