Reputation: 480
I am developping a Rest API with Silex framework and I use SecurityServiceProvider
. However, if a user sends bad credentials throw HTTP, I don't know how I can catch the error to display something like this :
{"status_code":401, "error_message":"Bad credentials"}
Below is a part of my code:
$app->register(new Silex\Provider\SecurityServiceProvider(), array(
'security.firewalls' => array(
'default' => array(
'pattern' => '^.*$',
'stateless' => true,
'http' => true,
'users' => $app->share(function() use ($app) {
return new App\Providers\UserProvider($app['db']);
}),
),
),
));
// ...
$app->error(function (\Exception $e, $code) use ($app) {
// This code is never executed in case of Bad credentials
// ...
return new JsonResponse($contentResponse, $statusCode);
});
Thank you in advance
EDIT
I've seen I can use $app['security.authentication.failure_handler.'.$name]
but it is never handled in my case.
$app['security.authentication.failure_handler.default'] = $app->share(function ($app) {
// This code is never executed
return new MySuccessHandler();
});
Is it because of 'http' => true
?
Upvotes: 1
Views: 542
Reputation: 480
Because of the structure of my code, I decided to check the error in the after
middleware, throw an exception and catch it with $app->error(...)
.
$app->after(function (Request $request, Response $response) {
// If Unauthorized
if ($response->getStatusCode() == 401)
throw new Exception('Unauthorized'); // This exception will be handled by "$app->error(...)"
});
$app->register(new Silex\Provider\SecurityServiceProvider(), array(
'security.firewalls' => array(
'default' => array(
'pattern' => '^.*$',
'stateless' => true,
'http' => true,
'users' => $app->share(function() use ($app) {
return new App\Providers\UserProvider($app['db']);
}),
),
),
));
// ...
$app->error(function (\Exception $e, $code) use ($app) {
// ...
return new JsonResponse($contentResponse, $statusCode);
});
Upvotes: 0
Reputation: 3590
Instead of using the generic error
function you can listen to the security events emitted by the security component, specifically to the security.authentication.failure one.
To do so, you just need to call the on
method:
<?php
use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent
//...
$app->on('security.authentication.failure', function(AuthenticationFailureEvent $event) {
// you can do some checks if you want, but there's no need...
return new JsonResponse($contentResponse, $statusCode);
});
Keep in mind that this is untested code.
Upvotes: 1
Reputation: 469
try it with
$app->error(function (\Exception $e, $code) use ($app) {
// This code is never executed in case of Bad credentials
if($e instanceof AuthenticationException){
return new JsonResponse(["status_code"=>401, "error_message"=>"Bad credentials"], 401);
}
// ...
return new JsonResponse($contentResponse, $statusCode);
});
Upvotes: 0