6

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
Alsciende
  • 26,583
  • 9
  • 51
  • 67
Razvan
  • 2,436
  • 18
  • 23

1 Answers1

5

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
aergistal
  • 29,947
  • 5
  • 70
  • 92
  • Looks like it's a correct answer to the original question. You deserve the bounty. Sadly, it doesn't answer my own question : adding a AuthenticationSuccess handler or listener to http_basic. – Alsciende Sep 03 '15 at 12:58
  • 1
    I finally managed to achieve my goal with a custom listener for `AuthenticationEvents::AUTHENTICATION_SUCCESS`, and checking `$event->getAuthenticationToken()->getRoles()` to see if a user authenticated (as opposed to an anonymous token). – Alsciende Sep 03 '15 at 13:18
  • @Alsciende Judging by the `SecurityBundle` reference configuration (http://symfony.com/fr/doc/current/reference/configuration/security.html) it seems there are no handlers for `http_basic`. – aergistal Sep 03 '15 at 13:38