ak2
ak2

Reputation: 465

Symfony: How to use the @Security annotation with ajax requests

I'd like to use the @Security annotation for controller actions which should be called by ajax requests. Problem is, if I use "form_login" for the firewall in security.yml and the the action is called by a user who is not logged in, symfony intercepts the response and sends a 302 redirect to the configured login page. Since it's an ajax request, the 302 redirect does not make sense here. Is there a (simple) way to change the behaviour of "form_login" to not send a 302 redirect but send a 401 code back to the client (ajax)? I can find a lot of information on how to overwrite the AuthenticationSuccessHandler and AuthenticationFaliureHandler for $request->isXmlHttpRequest() like: http://www.webtipblog.com/adding-an-ajax-login-form-to-a-symfony-project/

But that's only one part of it, this way you can avoid getting redirects when a user submits the form. But what I would like to do is sending a 401 back to the client not only when he already tries to login, but also instead of redirecting the user to a login-form URL because of a @Security annotation or "access_control" configuration.

How I can do it now:

class AjaxController extends Controller
{
    /**
     * @Route("/ajax/task/save")
     */
    public function ajaxAction()
    {
        $user = $this->getUser();
        if (!$user) {
            // load login-form in JS code 
            return new JsonResponse(array('authenticated'=> false), 401);
        }

        // do...
    }
}

but what I'd like to do is:

class AjaxController extends Controller
{
    /**
     * @Route("/ajax/task/save")
     * @Security("has_role('ROLE_USER')")
     */
    public function ajaxAction()
    {
        // do...
    }
}

But this way I have to make sure that not a 302 redirecting to the login-form is send to the client but something like my JsonResponse from the previous example.

How can I do this?

Upvotes: 2

Views: 1488

Answers (1)

Cristian
Cristian

Reputation: 1704

If I understand what you're looking for, you should be able to create a custom exception listener that returns a JSON response based on the content-type header and whatever status code you like before Symfony redirects the user.

http://symfony.com/doc/current/cookbook/service_container/event_listener.html

Upvotes: 1

Related Questions