-
Notifications
You must be signed in to change notification settings - Fork 5
Other options for hooking the Guard into Symfony's authentication
It is hard to make out which service is intended to do things like registering.
Disadvantage of replacing the security.authentication.listener.form service is that it only works for
form-based authentication. Other options where:
-
Replacing the security.authentication.manager service (AuthenticationProviderManager). One problem with this is that this service has no access to the request. Therefore it does not know the IP address of the login request. I guess that can be solved (if its service config is not too complex).
I don't think this service is meant to be overridden unless one needs to change the authentication process as a whole. Need to look into this option though. -
Replacing the security.authentication.provider.dao (DaoAuthenticationProvider) service. Also has no access to the request. Would probably not work with non-database providers like with one for Ldap, but neither would the current solution.
-
Adding an AuthenticationFailureHandler and an AuthenticationSuccessHandler. Successes and failures may be registered from here. This is not a good place for blocking, because attackers will still get the code executed that retieves the user and checks the password. Timing will then leak the (non)existence of the user, even if the login is blocked later by one of these handlers.
-
Replacing the UserChecker service. ::checkPreAuth could block attempts before the user is retrieved and the password checked, but there is no access to the request. And this service too is a likely candidate for application developers to replace, also leading to incompatibilty.
-
Adding a specific kernel event listener for kernel.request events. This seems to be a good option as none of the standard authentication services would have to be replaced, leaving all options open to the application developer, the user bundle and other security services. The request is available as well, so we know the ip addres. The login requests are diverted in an early stage, but that may be solved by setting priority lower then 128 (not tested). Finally we could add some other service to catch and store authentication results. BUT we would like to have the authentication token to get access to the username and possably the password. But \Symfony\Component\Security\Http\Firewall\UsernamePasswordFormAuthenticationListener::attemptAuthentication creates the token itself, so some other event listener will always be too early of too late. Same for \Symfony\Component\Security\Http\Firewall\BasicAuthenticationListener::handle and \Symfony\Component\Security\Http\Firewall\SimpleFormAuthenticationListener::attemptAuthentication. An option would be to duplicate the code that creates the token into some small service used by our specific listener, or in some way make it configurable.
-
Adding a specific kernel event listener for kernel.response events. Maybe login results could be cought from there, but there will certainly be differences depending on the type of Authentication Listener.
-
Replacing the security.exception_listener service. I am not sure if the primary login passes here. If so, Exceptions from the authentication can be caught and the results inferred from them. The request is available. But the existing exception handling code is probably very important and not very transparent so maintenance may become a problem. And we still have the problem of obtaining the user name. Furthermore there is a Cookbook page about changing the target path behavior so application developers may want to replace this service too.
Basically the disadvantage of having to develop different Guard classes for different kinds of authentication may only be solved by options 1, 2 and 5. Option 5, which could also do blocking of aditional paths.