我有一个旧的Symfony 3.1站点,我把它升级到Symfony 3.4.x,然后升级到Symfony 4.4.11,但是我没有将它升级到symfony flex。我修了很多东西,公共网站看起来也很管用。
我不得不重新构建身份验证,因为旧的身份验证与sf4不兼容。
我跟踪了这个https://symfony.com/doc/4.4/security/form_login_setup.html
这个:https://symfonycasts.com/screencast/symfony-security/make-user
最后,在成功的身份验证之后,当它重定向到管理区域时,它总是再次检查LoginFormAuthenticator,这显然不支持管理区域,并且它与匿名用户一起重定向回登录页面。
有许多关于这个问题的讨论,并尝试了我发现的所有东西,但我没有找到解决办法。即使调试它也不行。
保存在定义路径中的会话。它的id与浏览器中的PHPSESSID相同。站点运行HTTP协议。
security.yml
security:
encoders:
AppBundle\Entity\User:
algorithm: bcrypt
cost: 12
providers:
user_provider:
entity:
class: AppBundle:User
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt|error)|css|images|js)/
security: false
main:
stateless: true
pattern: ^/
anonymous: true
logout_on_user_change: true
guard:
authenticators:
- AppBundle\Security\LoginFormAuthenticator
form_login:
provider: user_provider
username_parameter: email
csrf_token_generator: security.csrf.token_manager
login_path: app_login
logout:
path: app_logout
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY }路由:
app_login:
path: /login
defaults: { _controller: AppBundle\Controller\BackendController:loginAction }
app_logout:
path: /logout
defaults: { _controller: AppBundle\Controller\BackendController:logoutAction }
app_admin:
path: /admin/{page}/{entry}
defaults: { _controller: AppBundle\Controller\BackendController:showAction, entry: null }User.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\EquatableInterface;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* User
*
* @ORM\Table(name="user")
* @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
*/
class User implements UserInterface, \Serializable, EquatableInterface
{
private $id;
// and so on
public function serialize()
{
return serialize(array(
$this->id,
$this->email,
$this->password
));
}
public function unserialize($serialized)
{
list (
$this->id,
$this->email,
$this->password,
) = unserialize($serialized);
}
public function getRoles()
{
return array('ROLE_ADMIN');
}
public function getUsername()
{
return $this->getEmail();
}
public function isEqualTo(UserInterface $user)
{
if (!$user instanceof User) {
return false;
}
if ($this->password !== $user->getPassword()) {
return false;
}
if ($this->salt !== $user->getSalt()) {
return false;
}
if ($this->email !== $user->getUsername()) {
return false;
}
return true;
}
}后端控制器:
class BackendController extends AbstractController
{
public function loginAction(AuthenticationUtils $authenticationUtils)
{
return $this->render('AppBundle:Backend:page.html.twig', array(
'email' => $authenticationUtils->getLastUsername(),
'error' => $authenticationUtils->getLastAuthenticationError()
));
}
public function logoutAction()
{
$this->container->get('security.token_storage')->setToken(null);
$this->container->get('request')->getSession()->invalidate();
}
public function showAction(Request $request, $page, $entry)
{
$this->denyAccessUnlessGranted('ROLE_ADMIN', null, 'Unable to access this page!');
// some logic
}
}LoginFormAuthentication.php
在这个例子中看起来是一样的,而且它是有效的。它成功地到达onAuthenticationSuccess()并重定向到管理区域。
dev.log
request.INFO: Matched route "app_login". {"route":"app_login"..}
security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"main","authenticators":1} []
security.DEBUG: Checking support on guard authenticator. {"firewall_key":"main","authenticator":"AppBundle\\Security\\LoginFormAuthenticator"} []
security.DEBUG: Calling getCredentials() on guard authenticator. {"firewall_key":"main","authenticator":"AppBundle\\Security\\LoginFormAuthenticator"} []
security.DEBUG: Passing guard token information to the GuardAuthenticationProvider {"firewall_key":"main","authenticator":"AppBundle\\Security\\LoginFormAuthenticator"} []
doctrine.DEBUG: SELECT t0.* FROM user t0 WHERE t0.email = ? LIMIT 1 ["email@me.com"] []
security.INFO: Guard authentication successful! {"token":"[object] (Symfony\\Component\\Security\\Guard\\Token\\PostAuthenticationGuardToken: PostAuthenticationGuardToken(user=\"email@me.com\", authenticated=true, roles=\"ROLE_ADMIN\"))","authenticator":"AppBundle\\Security\\LoginFormAuthenticator"} []
security.DEBUG: Guard authenticator set success response. Redirect response
security.DEBUG: Remember me skipped: it is not configured for the firewall.
security.DEBUG: The "AppBundle\Security\LoginFormAuthenticator" authenticator set the response. Any later authenticator will not be called {"authenticator":"AppBundle\\Security\\LoginFormAuthenticator"} []重定向后:
request.INFO: Matched route "app_admin". {"route":"app_admin" ..}
security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"main","authenticators":1} []
security.DEBUG: Checking support on guard authenticator. {"firewall_key":"main","authenticator":"AppBundle\\Security\\LoginFormAuthenticator"} []
security.DEBUG: Guard authenticator does not support the request. {"firewall_key":"main","authenticator":"AppBundle\\Security\\LoginFormAuthenticator"} []
security.INFO: Populated the TokenStorage with an anonymous Token. [] []
security.DEBUG: Access denied, the user is not fully authenticated; redirecting to authentication entry point.
security.DEBUG: Calling Authentication entry point. [] []发布于 2020-08-17 18:21:23
我的同事搞清楚了问题出在哪里。实际上,上面的代码有多个问题。
使用https://github.com/symfony/symfony/blob/4.4/UPGRADE-4.0.md#security
$this->salt !== $user->getSalt(),但没有序列化,所以工作解决方案看起来像这个
same
security.yml
security:
encoders:
AppBundle\Entity\User:
algorithm: bcrypt
cost: 12
providers:
user_provider:
entity:
class: AppBundle:User
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt|error)|css|images|js)/
security: false
main:
anonymous: ~
provider: user_provider
form_login:
login_path: app_login
check_path: app_login
default_target_path: app_admin
logout:
path: app_logout
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY }User.php
class User implements UserInterface, \Serializable, EquatableInterface
{
// ..
public function serialize()
{
return serialize(array(
$this->id,
$this->email,
$this->password,
$this->salt,
));
}
public function unserialize($serialized)
{
list (
$this->id,
$this->email,
$this->password,
$this->salt
) = unserialize($serialized, array('allowed_classes' => false));
}
public function isEqualTo(UserInterface $user)
{
if (!$user instanceof User) {
return false;
}
if ($user->getId() == $this->getId()) {
return true;
}
if ($this->password !== $user->getPassword()) {
return false;
}
if ($this->salt !== $user->getSalt()) {
return false;
}
if ($this->email !== $user->getUsername()) {
return false;
}
return true;
}
}发布于 2020-08-17 17:11:32
必须更改保护身份验证器AppBundle\Security\LoginFormAuthenticator
这向守卫解释,您只需要检查登录页面上的凭据。
public function supports(Request $request)
{
return 'login_route' === $request->attributes->get('_route') && $request->isMethod('POST');
}https://stackoverflow.com/questions/63454223
复制相似问题