Fosrestbundle: Rückgabe von JSON/XML -Meta -Daten für "schlechte Anmeldeinformationen" Ausnahme

StackOverflow https://stackoverflow.com/questions/19836178

Frage

Ich benutze Fosrestbundle für meine REST -API und bisher war es ein großartiges Werkzeug. Ich verwende HTTP Basic Auth und in den meisten Fällen funktioniert es gut. Ich habe jedoch Probleme mit dem Ausnahmeverhalten des Bundle, wenn schlechte Anmeldeinformationen eingereicht werden. Bei der Handhabung von Ausnahmen (über die integrierten Authentifizierungshandler oder die Konfiguration der Ausnahmezuordnung) gibt mir das Bundle immer eine Antwort mit dem richtigen HTTP -Status und JSON/XML -Inhalt, ähnlich wie folgt:

{
   "code": 401,
   "message": "You are not authenticated"
}

Das ist in Ordnung, es funktioniert auch, wenn keine Authentifikation Informationen werden überhaupt eingereicht. Bei der Einreichung jedoch schlechte Referenzen (zB unbekannte Benutzername oder falsches Passwort) Ich erhalte den HTTP -Code 401 schlechte Anmeldeinformationen (was in Ordnung ist) mit einer leeren Nachricht. Stattdessen hätte ich etwas Ähnliches wie das json oben erwartet.

Ist es ein Fehler oder ein Konfigurationsproblem auf meiner Seite? Ich würde auch gerne wissen, wie diese Art von Authentifizierungsfehlern genau vom Bündel behandelt werden, da die Überschreibung des Bündels genau behandelt wird BadCredentialsExceptionStatuscode in der codes Der Abschnitt des Abschnitts der Ausnahmekonfiguration des Bundle scheint ignoriert zu werden.

Vielen Dank!

War es hilfreich?

Lösung

Okay, nachdem ich noch mehr in den Code des Bundles eingegraben hatte, habe ich es herausgefunden. Das Problem ergibt sich aus der Art und Weise, wie schlechte Anmeldeinformationen von Symfonys HTTP -Basis -Authentifizierungs -Impementation behandelt werden. Das 401 Bad Credentials Die Antwort ist eine benutzerdefinierte Antwort, die von erstellt wurde durch BasicAuthenticationEntryPoint, was von der genannt wird BasicAuthenticationListener's handle Funktion, unmittelbar nach einem AuthenticationException wurde in die gleiche Funktion geworfen. Es gibt also keine Möglichkeit, diese Ausnahme mit einem Zuhörer zu fangen:

public function handle(GetResponseEvent $event)
{
    $request = $event->getRequest();

    if (false === $username = $request->headers->get('PHP_AUTH_USER', false)) {
        return;
    }

    if (null !== $token = $this->securityContext->getToken()) {
        if ($token instanceof UsernamePasswordToken && $token->isAuthenticated() && $token->getUsername() === $username) {
            return;
        }
    }

    if (null !== $this->logger) {
        $this->logger->info(sprintf('Basic Authentication Authorization header found for user "%s"', $username));
    }

    try {
        $token = $this->authenticationManager->authenticate(new UsernamePasswordToken($username, $request->headers->get('PHP_AUTH_PW'), $this->providerKey));
        $this->securityContext->setToken($token);
    } catch (AuthenticationException $failed) {
        $this->securityContext->setToken(null);

        if (null !== $this->logger) {
            $this->logger->info(sprintf('Authentication request failed for user "%s": %s', $username, $failed->getMessage()));
        }

        if ($this->ignoreFailure) {
            return;
        }

        $event->setResponse($this->authenticationEntryPoint->start($request, $failed));
    }
}

Der Einstiegspunkt start Die Funktion erstellt die benutzerdefinierte Antwort ohne Ausnahmen:

public function start(Request $request, AuthenticationException $authException = null)
{
    $response = new Response();
    $response->headers->set('WWW-Authenticate', sprintf('Basic realm="%s"', $this->realmName));
    $response->setStatusCode(401, $authException ? $authException->getMessage() : null);

    return $response;
}

Die Faust if-Ceil in der handle Die obige Funktion erklärt auch, warum es im Fall von "überhaupt keine Benutzeranmeldeinformationen" funktioniert, da der Hörer in diesem Fall nur nicht mehr versucht, den Benutzer zu authentifizieren, und daher eine Ausnahme von Symfonys Firewall -Hörern ausgelöst wird (nicht ganz sicher, wo genau), also fosrestbundle's AccessDeniedListener ist in der Lage, das zu fangen AuthenticationException und tun sein Ding.

Andere Tipps

Sie können sich ausdehnen AccessDeniedListener Sagen Sie Fosrestbundle, Sie sollen Ihren eigenen Hörer mit dem Parameter verwenden %fos_rest.access_denied_listener.class%. (Service -Definition)

parameters:
    fos_rest.access_denied_listener.class: Your\Namespace\For\AccessDeniedListener

Fügen Sie dann eine zusätzliche Prüfung nach hinzu. BadCredentialsException und emmit an HttpException Mit dem gewünschten Code/der gewünschten Meldung ähnlich wie bei der Authentifizierungsprüfung bei der Authentifizierung Zeile 70.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top