symfony 身份验证程序不支持请求

jdgnovmf  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(98)

我有一个Symfony 5.1项目,具有登录功能。
当我使用Symfony CLI命令symfony serve时,localhost上的登录正常。但是当我尝试通过Docker进行相同的登录时,什么也没有发生。
在我的nginx容器的日志中,我可以看到这样的消息:

172.19.0.1 - - [24/Nov/2020:13:31:40 +0000] "POST /login HTTP/1.1" 302 282 "http://localhost:8088/login" "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36"

2020/11/24 13:31:41 [error] 27#27: *122 FastCGI sent in stderr: "PHP message: [info] Matched route "app_login".
PHP message: [debug] Checking for authenticator support.
PHP message: [debug] Checking support on authenticator.
PHP message: [debug] Authenticator does not support the request. ['firewall_name' => 'main', 'authenticator' => 'Symfony\Component\Security\Guard\Authenticator\GuardBridgeAuthenticator']

这是我的config/packages/security.yaml

security:
    enable_authenticator_manager: true

    providers:
        users:
            entity:
                class: 'App\Entity\User'

    encoders:
        App\Entity\User:
            algorithm: auto

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            anonymous: false
            lazy: true
            provider: users
            guard:
                authenticators:
                    - App\Security\LoginFormAuthenticator
            logout:
                path: app_logout
                # where to redirect after logout
                target: home

    role_hierarchy:
        ROLE_ADMIN: ROLE_USER

    access_control:
        - { path: ^/admin, roles: ROLE_ADMIN }

这是我的docker/nginx/default.conf

server {
    listen 80;
    index index.php index.html;
    server_name localhost;
    error_log /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/app/public;
    proxy_buffer_size 128k;
    proxy_buffers 4 256k;
    proxy_busy_buffers_size 256k;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_buffer_size 128k;
        fastcgi_buffers 4 256k;
        fastcgi_busy_buffers_size 256k;
    }
}

这是我的docker/php/Dockerfile

FROM php:7.4-fpm

# Install Composer
RUN curl -sS https://getcomposer.org/installer | php -- \
    --install-dir=/usr/local/bin \
    --filename=composer

# Install MySQL
RUN docker-php-ext-install mysqli pdo pdo_mysql

WORKDIR /var/www/app

我的src/Security/LoginFormAuthenticator.php

<?php

namespace App\Security;

...
use App\Entity\User;
...

class LoginFormAuthenticator extends AbstractFormLoginAuthenticator implements PasswordAuthenticatedInterface
{
    use TargetPathTrait;

    public const LOGIN_ROUTE = 'app_login';

    private $entityManager;
    private $urlGenerator;
    private $csrfTokenManager;
    private $passwordEncoder;

    public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager, UserPasswordEncoderInterface $passwordEncoder)
    {
        $this->entityManager = $entityManager;
        $this->urlGenerator = $urlGenerator;
        $this->csrfTokenManager = $csrfTokenManager;
        $this->passwordEncoder = $passwordEncoder;
    }

    public function supports(Request $request)
    {
        return self::LOGIN_ROUTE === $request->attributes->get('_route')
            && $request->isMethod('POST');
    }

    public function getCredentials(Request $request)
    {
        $credentials = [
            'email' => $request->request->get('email'),
            'password' => $request->request->get('password'),
            'csrf_token' => $request->request->get('_csrf_token'),
        ];
        $request->getSession()->set(
            Security::LAST_USERNAME,
            $credentials['email']
        );

        return $credentials;
    }

    public function getUser($credentials, UserProviderInterface $userProvider)
    {
        $token = new CsrfToken('authenticate', $credentials['csrf_token']);
        if (!$this->csrfTokenManager->isTokenValid($token)) {
            throw new InvalidCsrfTokenException();
        }

        $user = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $credentials['email']]);

        if (!$user) {
            // fail authentication with a custom error
            throw new CustomUserMessageAuthenticationException('Email could not be found.');
        }

        return $user;
    }

    public function checkCredentials($credentials, UserInterface $user)
    {
        return $this->passwordEncoder->isPasswordValid($user, $credentials['password']);
    }

    public function getPassword($credentials): ?string
    {
        return $credentials['password'];
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey)
    {
        if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
            return new RedirectResponse($targetPath);
        }

        return new RedirectResponse($this->urlGenerator->generate('home'));
    }

    protected function getLoginUrl()
    {
        return $this->urlGenerator->generate(self::LOGIN_ROUTE);
    }
}

我做错了什么,我的Docker不能识别我的App\Security\LoginFormAuthenticator作为身份验证器?
提前感谢!

编辑:2021年2月22日

它看起来像是表单正在无错误地重定向自己。我猜使用了错误的验证器,但在我的security.yaml文件中,您可以看到正确的保护。

nbysray5

nbysray51#

删除anonymous: false设置就可以了。
感谢@Cerad的帮助!

相关问题