1
votes

I'm trying to setup the FOSRestBundle to catch authentication exceptions. My config:

fos_rest:
  param_fetcher_listener: true
  body_listener: true
  format_listener: true
  view:
    default_engine: php
  format_listener:
    default_priorities: ['json']
    fallback_format: json
    prefer_extension: false
  access_denied_listener:
    json: true
  exception:
    codes:
      Symfony\Component\Security\Core\Exception\AccessDeniedException: 403

twig:
  exception_controller: FOS\RestBundle\Controller\ExceptionController::showAction

This config will catch exceptions when they are thrown in a controller, but not when they are thrown from within the security component (i.e. if a user auth fails). Is something wrong with my config, or is the FOSRestBundle simply not designed to intercept exceptions at that point in the stack?

It's worth mentioning that I'm using a custom auth provider based on the WSSE tutorial here:

http://symfony.com/doc/current/cookbook/security/custom_authentication_provider.html

2
Hi, I'm having the same issue here, have you found a solution for it?Jukurrpa
Sorry, no. We ended-up using an entirely different authentication method in the end!Mathew

2 Answers

0
votes

authentication exceptions should normally be handled by the authentication failure handler service.

The authentication handlers can be found in your security.yml:

security:
    firewalls:
       firewall_name:
           form_login:
               # ...
               failure_path:    /foo
               failure_forward: false
               failure_path_parameter: _failure_path
               failure_handler: some.service.id
               success_handler: some.service.id

see the configuration reference.

See this question for information on how to implement your own failure handler.

0
votes

I was having this exact same issue. My issue was that WsseListener wasnt actually throwing the exception. Their tutorial has these code:

try {
            $authToken = $this->authenticationManager->authenticate($token);
            $this->securityContext->setToken($authToken);

        return;
    } catch (AuthenticationException $failed) {
        // ... you might log something here

        // To deny the authentication clear the token. This will redirect to the login page.
        // Make sure to only clear your token, not those of other authentication listeners.
        // $token = $this->securityContext->getToken();
        // if ($token instanceof WsseUserToken && $this->providerKey === $token->getProviderKey()) {
        //     $this->securityContext->setToken(null);
        // }
        // return;

        // Deny authentication with a '403 Forbidden' HTTP response
        $response = new Response();
        $response->setStatusCode(403);
        $event->setResponse($response);

    }

    // By default deny authorization
    $response = new Response();
    $response->setStatusCode(403);
    $event->setResponse($response);
}

Note how the AuthenticationException is getting caught and then its returning a HTTP Response.

I fixed mine by just throwing $failed:

catch (AuthenticationException $failed) {
     throw $failed
}