I am extending the authentication failure handler and everything is mainly working ok, but for one small problem.
This is my services.yml:
http.utils.class:
class: Symfony\Component\Security\Http\HttpUtils
auth.fail:
class: Acme\MyBundle\AuthenticationFailure
arguments:
- @http_kernel
- @http.utils.class
- []
I have set this to be used in security.yml:
failure_handler: auth.fail
This is my Acme\MyBundle\AuthenticationFailure.php:
namespace Acme\MyBundle;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationFailureHandler;
use Symfony\Component\HttpFoundation\Response;
class AuthenticationFailure extends DefaultAuthenticationFailureHandler
{
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
//do something
}
}
The problem is that the options I've set in security.yml are ignored. I know the third parameter of the _construct method of the class is the $options array, and I've not passed anything in as the third parameter (in services.yml), so I'm guessing this is the problem and a solution could be to just pass the values in. I'm guessing I could also do something like this:
arguments:
- @http_kernel
- @http.utils.class
- %security.firewalls.secure_area.form_login%
....I've not tested as the problem is this is hard-coding that in services.yml and it isn't ideal as if I changed the name of secure_area it would break. Surely these values are available in a better way?
I see you're trying to pass the login_path to your authentication failure handler...
... you should inject @router
, adapt the __construct
method and generate the url with the route name ( not pattern ) used by your firewall inside the auth failure handler. then redirect the user there...
login_path: your_login_route_name # <- not a pattern like /login
this way changing the name of the firewall will not break your application!
if you don't even want to break the application when changing the route name you can make this configurable aswell:
config.yml
parameters:
login.route_name: my_login_route_name
routing.yml
%login.route_name%:
pattern: /login
security.yml
security:
firewalls:
your_firewall_name:
failure_handler: auth.fail
login_path: %login.route_name%
services.yml
auth.fail:
arguments:
- # ...
- @router
- %login.route_name%
Acme\MyBundle\AuthenticationFailure
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
// ...
protected $router;
protected $loginRoute;
public function __construct(
/** ... other arguments **/,
RouterInterface $router,
$loginRoute
)
{
// ..
$this->router = $router;
$this->loginRoute = $loginRoute;
}
public function onAuthenticationFailure(
Request $request,
AuthenticationException $exception
)
{
// ...
return new RedirectResponse( $this->router->generate($this->loginRoute) );
}
Tip regarding your suggestion
( ... using something like %security.firewalls.secure_area.form_login%
)
you cannot access the security configuration directly ( these are not parameters - you can't use %security.firewall.whatever%
! ) ...
The the default $options
passed to __construct
has to be an array ...
... so you might need to surround your passed parameters by []
if those parameters are not an array.
arguments:
- [ %parameter1% , %parameter2% ]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With