Search code examples
symfonybasic-authentication

How to configure http_basic firewall in Symfony to return JSON in response body?


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

I'd like to have it return a custom JSON (eg: {success: false, error: 401}). Is this possible?

Here's my configuration:

security:
    firewalls:
        api:
            http_basic:
                provider: myprovider

Solution

  • You need to use a custom AuthenticationEntryPoint. Create a class implementing the AuthenticationEntryPointInterface:

    <?php
    
    namespace AppBundle;
    
    use Symfony\Component\Security\Core\Exception\AuthenticationException;
    use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\HttpFoundation\Request;
    
    class CustomBasicAuthenticationEntryPoint implements AuthenticationEntryPointInterface {
    
        private $realmName;
    
        public function __construct($realmName) {
            $this->realmName = $realmName;
        }
    
        public function start(Request $request, AuthenticationException $authException = null) {
            $content = array('success' => false, 'error' => 401);
    
            $response = new Response();
            $response->headers->set('WWW-Authenticate', sprintf('Basic realm="%s"', $this->realmName));
            $response->headers->set('Content-Type', 'application/json');
            $response->setContent(json_encode($content))
                    ->setStatusCode(401);
            return $response;
        }    
    }
    

    The class needs to be accessible as a service so add it to services.yml. Pass the realm as an argument.

    custom_basic_authentication_entry_point:
             class: AppBundle\CustomBasicAuthenticationEntryPoint
             arguments: [ main ]
    

    You can then use it in security.yml:

    firewalls:
           main:
                anonymous: ~
                http_basic: ~
                entry_point: custom_basic_authentication_entry_point