Symfony 6 ApiKeyAuthenticator 与 SelfValidatingPassport 取代了守卫?

Rod*_*igo 0 php symfony api-platform.com symfony6

我使用 api-platform 将 symfony 5.1 api 迁移到 symfony 6。
我的应用程序有自己的用户和密码逻辑,与普通用户数据库不同,因此我必须创建 UserRepository 和 UserProvider。
我创建了一个具有登录功能的控制器,用于检查凭据并返回令牌。
在 上symfony 5,我实现了 AbstractGuardAuthenticator 来验证令牌并加载用户。
我symfony 6使用实现 AbstractAuthenticator 的新系统(个人意见:不如守卫清晰)。

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
Run Code Online (Sandbox Code Playgroud)
<?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);
    }


}
Run Code Online (Sandbox Code Playgroud)

当我对需要登录用户的端点进行简单调用时,例如:

GET http://localhost:8000/api/categories
Accept: application/json
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQi[...]
Run Code Online (Sandbox Code Playgroud)

我期望一个类别列表,但我收到来自以下位置的 json onAuthenticationSuccess:

GET http://localhost:8000/api/categories
Accept: application/json
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQi[...]
Run Code Online (Sandbox Code Playgroud)

所以我认为我误解了安全系统。请帮我。
我做错了什么?

小智 5

很简单,你几乎已经拥有它了。 onAuthenticationSuccess必须返回 null 才能让您的请求继续。
返回 json: 时,您正在中断原始请求{"result": "ok"}。

public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
     return null;
}
Run Code Online (Sandbox Code Playgroud)