D'accord, après avoir creusé un peu plus dans le code du bundle, je l'ai compris. Le problème résulte de la façon dont les mauvaises informations d'identification sont gérées par la souci d'authentification de base HTTP de Symfony. La 401 Bad Credentials
La réponse est une réponse personnalisée créée par BasicAuthenticationEntryPoint
, qui est appelé par le BasicAuthenticationListener
's handle
fonction, immédiatement après un AuthenticationException
a été lancé dans la même fonction. Il n'y a donc aucun moyen d'attraper cette exception avec un auditeur:
public function handle(GetResponseEvent $event)
{
$request = $event->getRequest();
if (false === $username = $request->headers->get('PHP_AUTH_USER', false)) {
return;
}
if (null !== $token = $this->securityContext->getToken()) {
if ($token instanceof UsernamePasswordToken && $token->isAuthenticated() && $token->getUsername() === $username) {
return;
}
}
if (null !== $this->logger) {
$this->logger->info(sprintf('Basic Authentication Authorization header found for user "%s"', $username));
}
try {
$token = $this->authenticationManager->authenticate(new UsernamePasswordToken($username, $request->headers->get('PHP_AUTH_PW'), $this->providerKey));
$this->securityContext->setToken($token);
} catch (AuthenticationException $failed) {
$this->securityContext->setToken(null);
if (null !== $this->logger) {
$this->logger->info(sprintf('Authentication request failed for user "%s": %s', $username, $failed->getMessage()));
}
if ($this->ignoreFailure) {
return;
}
$event->setResponse($this->authenticationEntryPoint->start($request, $failed));
}
}
Le point d'entrée start
La fonction crée la réponse personnalisée, sans exceptions impliquées:
public function start(Request $request, AuthenticationException $authException = null)
{
$response = new Response();
$response->headers->set('WWW-Authenticate', sprintf('Basic realm="%s"', $this->realmName));
$response->setStatusCode(401, $authException ? $authException->getMessage() : null);
return $response;
}
Le poing if
-crave dans le handle
La fonction ci-dessus explique également pourquoi cela fonctionne dans le cas de "aucune information d'identification du tout", car dans ce cas, l'auditeur cesse d'essayer d'authentifier l'utilisateur, et donc une exception sera lancée par les auditeurs de pare-feu de Symfony (je ne sais pas trop où Exactement), donc Fosrestbundle AccessDeniedListener
est capable d'attraper le AuthenticationException
Et faites son truc.