Search code examples
securitysymfony4basic-authenticationevent-listener

How to configure http_basic firewall in Symfony 4 to return JSON in response body on authentication failure?


By default, when you configure a http_basic firewall in Symfony, the firewall will return "401 Unauthorized" and an empty body for requests with invalid credentials.

I'd like to have it return a custom JSON (eg: {'errorCode' => 'AUTHORIZATION_FAILURE', 'errorMessage' => 'The provided credentials are not valid'}). Is this possible?

My onAuthenticationFailure method does not return my custom response. It returns the default response.

My AuthenticationListener class that will subscribe to these events:

<?php
namespace App\EventListener;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;

class AuthenticationListener
{   
    public function onAuthenticationFailure(AuthenticationFailureEvent $event)
    {
        //executes on failed login
        $content = array('errorCode' => 'AUTHORIZATION_FAILURE', 'errorMessage' => 'The provided credentials are not valid');
        // dd(json_encode($content));

        //the bellow code is not working
        $response = new Response();
        $response->headers->set('Content-Type', 'application/json');
        $response->setContent(json_encode($content))
                ->setStatusCode(200);

        return $response;
    }
}
?>

my security YAML

firewalls:
        api:
            pattern: ^/1
            anonymous: false
            provider: in_api
            http_basic: ~

my service YAML

# authentication failure event listener
    acme.security.authentication_failure_event_listener:
        class: App\EventListener\AuthenticationListener
        arguments: [ api ]
        tags:
            - { name: kernel.event_listener, priority: 100, event: security.authentication.failure, method: onAuthenticationFailure }

Solution

  • When I use header('Content-Type: application/json');echo json_encode($content);exit; it returns the expected result.