0

I migrating a symfony 5.1 api to symfony 6 with api-platform.
My app has it's own user and password logic different to common user database so I had to create my UserRepository and UserProvider.
I have created a controller with Login functionality that checks credentials and returns a token.
On symfony 5, I had implemented an AbstractGuardAuthenticator to verify the token and load the user.
On symfony 6 I use the new system implementing an AbstractAuthenticator (Personal opinion: less clear than guard).

security:
    enable_authenticator_manager: true
# [...]
    providers:
        # used to reload user from session & other features (e.g. switch_user)
        api_user_provider:
            id: App\Security\UserProvider

    firewalls:
# [...]
        api:
            pattern: ^/api/
            stateless: true
            provider: api_user_provider
            custom_authenticators:
                - App\Security\TokenAuthenticator
<?php

namespace App\Security;

// usings

class TokenAuthenticator extends AbstractAuthenticator
{
// [...]
    public function supports(Request $request): ?bool
    {
        if ( $request->headers->has('Authorization') ) {
            return true;
        } else {
            throw new AuthenticationException('Authorization header is missing');
        }
    }

    public function authenticate(Request $request): Passport
    {
        $token = $this->getToken($request);
       
        return new SelfValidatingPassport(
            new UserBadge($token, function ($token): UserInterface {
                return $this->getUserFromToken($token);
            }), []
        );


    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
    {
        return New JsonResponse(["result"=> "ok"]);
    }

    public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
    {
        return new JsonResponse(["result" => "error"], Response::HTTP_UNAUTHORIZED);
    }


}

When I make a simple call to an Endpoint that requires the user to be logged, e.g:

GET http://localhost:8000/api/categories
Accept: application/json
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQi[...]

I expect a list of categories, but I receive a json from onAuthenticationSuccess:

{"result":"ok"}

So I think I'm missunderstanding the security system. Please help me.
What I'm doing wrong?

Rodrigo
  • 131
  • 1
  • 6

1 Answers1

4

It's simple, you almost had it. onAuthenticationSuccess must return null to let your request continue.
Your are interrupting your original request when returning a json: {"result": "ok"}.

public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
     return null;
}
Martin
  • 343
  • 2
  • 11