我正在尝试在Symfony 4.1上实现带有保护的FOSUserBundle。 这是我的身份验证者:
<?php
namespace App\Security;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
class LoginFormAuthenticator extends AbstractFormLoginAuthenticator
{
use TargetPathTrait;
private $em;
private $router;
private $passwordEncoder;
private $csrfTokenManager;
public function __construct(EntityManagerInterface $em, RouterInterface $router, UserPasswordEncoderInterface $passwordEncoder, CsrfTokenManagerInterface $csrfTokenManager)
{
$this->em = $em;
$this->router = $router;
$this->passwordEncoder = $passwordEncoder;
$this->csrfTokenManager = $csrfTokenManager;
}
public function getCredentials(Request $request)
{
$username = $request->request->get('_username');
$password = $request->request->get('_password');
$csrfToken = $request->request->get('_csrf_token');
if (false === $this->csrfTokenManager->isTokenValid(new CsrfToken('authenticate', $csrfToken))) {
throw new InvalidCsrfTokenException('Invalid CSRF token.');
}
$request->getSession()->set(
Security::LAST_USERNAME,
$username
);
return [
'username' => $username,
'password' => $password,
];
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
$username = $credentials['username'];
return $this->em->getRepository('App:User')
->findOneBy(['email' => $username]);
}
public function checkCredentials($credentials, UserInterface $user)
{
$password = $credentials['password'];
if ($this->passwordEncoder->isPasswordValid($user, $password)) {
return true;
}
return false;
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
$targetPath = null;
// if the user hit a secure page and start() was called, this was
// the URL they were on, and probably where you want to redirect to
$targetPath = $this->getTargetPath($request->getSession(), $providerKey);
if (!$targetPath) {
$targetPath = $this->router->generate('homepage');
}
return new RedirectResponse($targetPath);
}
protected function getLoginUrl()
{
return $this->router->generate('fos_user_security_login');
}
/**
* Does the authenticator support the given Request?
*
* If this returns false, the authenticator will be skipped.
*
* @param Request $request
*
* @return bool
*/
public function supports(Request $request)
{
if($request->attributes->get('_route') !== 'fos_user_security_login'){
return false;
}
}
}
这是我的security.yaml文件:
security:
encoders:
App\Entity\User: bcrypt
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
logout: ~
guard:
authenticators:
- App\Security\LoginFormAuthenticator
# form_login:
# csrf_token_generator: security.csrf.token_manager
remember_me:
secret: '%env(APP_SECRET)%'
access_control:
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }
还有fos_user.yaml:
fos_user:
db_driver: 'orm'
user_class: App\Entity\User
firewall_name: main
service:
mailer: fos_user.mailer.twig_swift
from_email:
address: "admin@test.com"
sender_name: "test"
registration:
form:
type: App\Form\UserRegistrationFormType
每当我登录时,都会出现以下错误:
必须使用以下命令配置要由防火墙处理的检查路径 您的安全防火墙配置中的form_login。
我已经安装了安全捆绑包,并尝试通过官方文档中提供的步骤进行操作: https://symfony.com/doc/current/security/guard_authentication.html
我遵循了KnpUniversity上的教程,但这是针对Symfony 3的,看来事情不再以相同的方式起作用了。
肯定有我看不到的东西。
任何建议将不胜感激。
版本信息: -Symfony ^ 4.1 -FOSUserBundle ^ 2.1 -安全卫士^ 4.1
答案 0 :(得分:0)
我认为这将帮助您更好地了解什么是symfony Guard和fos用户捆绑包。 Symfony Guard - You don't need FOSUserBundle
答案 1 :(得分:0)
提示:我有一个类似的问题。如果我没记错的话,您必须删除fos用户捆绑包路由中定义的登录页面的路由。我知道我模棱两可,但请检查路线。在使用Guard进行身份验证时,它正在寻找fosuser登录页面。