我无法让身份验证工作,但它似乎只在非常特殊的情况下发生。身份验证是通过第三方API完成的,所以我编写了自己的用户提供程序类,在该类中是一些同步API和Symfony之间数据的代码,作为同步过程的一部分,它决定了用户应该拥有哪些角色。 执行此操作后,它通过ManyToMany关系设置角色和用户之间的关系。
我的User对象中的getRoles()方法从数据库中获取角色对象并将其转换为字符串数组,角色名称来自我的数据库,并且都以ROLE _开头。
如果我使用一个没有额外角色的帐户登录,它可以正常工作,但是如果我登录到应该有角色的帐户,我只会被发送回登录屏幕而没有错误消息。
我检查了日志并看到了这些条目:
security.INFO: User "test105@example.com" has been authenticated successfully [] []
event.DEBUG: Notified event "security.interactive_login" to listener "Pogo\MyBundle\Listener\LoginListener::onSecurityInteractivelogin". [] []
event.DEBUG: Listener "Symfony\Component\Security\Http\Firewall::onKernelRequest" stopped propagation of the event "kernel.request". [] []
event.DEBUG: Listener "Symfony\Bundle\FrameworkBundle\EventListener\RouterListener" was not called for event "kernel.request". [] []
event.DEBUG: Listener "Symfony\Bundle\AsseticBundle\EventListener\RequestListener" was not called for event "kernel.request". [] []
event.DEBUG: Notified event "kernel.response" to listener "Symfony\Component\Security\Http\Firewall\ContextListener::onKernelResponse". [] []
security.DEBUG: Write SecurityContext in the session [] []
event.DEBUG: Notified event "kernel.response" to listener "Symfony\Component\HttpKernel\EventListener\ResponseListener::onKernelResponse". [] []
event.DEBUG: Notified event "kernel.response" to listener "Symfony\Bundle\SecurityBundle\EventListener\ResponseListener::onKernelResponse". [] []
event.DEBUG: Notified event "kernel.response" to listener "Symfony\Bridge\Monolog\Handler\FirePHPHandler::onKernelResponse". [] []
event.DEBUG: Notified event "kernel.response" to listener "Sensio\Bundle\FrameworkExtraBundle\EventListener\CacheListener::onKernelResponse". [] []
event.DEBUG: Notified event "kernel.response" to listener "Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelResponse". [] []
event.DEBUG: Notified event "kernel.response" to listener "Symfony\Bundle\WebProfilerBundle\EventListener\WebDebugToolbarListener::onKernelResponse". [] []
event.DEBUG: Notified event "kernel.request" to listener "Symfony\Bundle\FrameworkBundle\EventListener\RouterListener::onEarlyKernelRequest". [] []
event.DEBUG: Notified event "kernel.request" to listener "Symfony\Bundle\FrameworkBundle\EventListener\SessionListener::onKernelRequest". [] []
event.DEBUG: Notified event "kernel.request" to listener "Symfony\Component\Security\Http\Firewall::onKernelRequest". [] []
security.INFO: Populated SecurityContext with an anonymous Token [] []
event.DEBUG: Notified event "kernel.exception" to listener "Symfony\Component\Security\Http\Firewall\ExceptionListener::onKernelException". [] []
security.DEBUG: Access denied (user is not fully authenticated); redirecting to authentication entry point [] []
security.DEBUG: Calling Authentication entry point [] []
我不明白它是如何在顶部进行身份验证的,然后一旦它检查防火墙就会发现自己有一个匿名令牌,这就是为什么它可能会把我送回登录界面。
我的防火墙/ access_control设置是:
firewalls:
public:
pattern: /.*
anonymous: true
tessitura_login:
login_path: /account/login
check_path: /secure/login_check
logout:
path: /secure/logout
target: /
access_control:
- { path: ^/secure/.*, role: ROLE_USER }
- { path: ^/admin.*, role: ROLE_ADMIN }
- { path: ^/account/login/?, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: /.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
对此的任何帮助都会受到高度赞赏,我现在花了几个小时就完成了这件事。我完全被难过了。
答案 0 :(得分:2)
在使用电话号码作为用户名并且未在refreshUser()
方法中指定用户名属性时出现此无提示失败问题,该方法应为:
public function refreshUser(UserInterface $customer)
{
$class = get_class($customer);
if( !$this->supportsClass($class) ) {
throw new UnsupportedUserException("Instances of \"{$class}\" are not supported");
}
return $this->loadUserByUsername($customer->getPhoneNumber()); // <-- This is it!
}
我认为我不是唯一一个错过它的人,可能有所帮助。
答案 1 :(得分:1)
破坏的会话存储对我造成了这种情况。我正在使用PdoSessionHandler并且令人失望地没有给出明确的错误或日志消息。
答案 2 :(得分:0)
我也经历过同样的经历。当我的用户登录时,我会通过以下几个语句检查他的角色:
if(true === $this->get('security.context')->isGranted('ROLE_MANAGER')){
//return redirect
}
if(true === $this->get('security.context')->isGranted('ROLE_USER')){
//return redirect
}
//throw error
有些用户不时会收到错误。我想这是因为同样的原因。用户以某种方式进行了身份验证但尚未获得其角色。
我无法重现自己的问题。我刚收到用户的错误报告。
答案 3 :(得分:0)
我也经历过同样的经历。对我而言,这是因为/ tmp分区已满,因此会话可以存储在服务器端,并且可以重定向到nex
答案 4 :(得分:0)
登录我的系统时遇到同样的问题,其中会话被配置为存储在memcache中但memcached未运行。如上所述,遗憾的是它没有给出更好的错误信息。
希望能帮助别人节省一些时间; - )
答案 5 :(得分:0)
我在用户登录时遇到了同样的问题我使用了sonata管理包,我也在使用PdoSessionHandler
的数据库会话
session.handler.pdo:
class: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
arguments: ["@pdo", %pdo.db_options%]
第一个问题,当我创建一个具有大量角色/权限的组时,数据在字段中被截断,因此我使用longtext
更改了我的角色字段并更改了ROW_FORMAT=COMPRESSED
ALTER TABLE `fos_group` CHANGE `roles` `roles` LONGTEXT NOT NULL COMMENT '(DC2Type:array)';
ALTER TABLE `fos_group`
ENGINE=INNODB
ROW_FORMAT=COMPRESSED
KEY_BLOCK_SIZE=8;
它完成工作并将所有角色/权限保存到字段中作为完整的序列化字符串。但是用户无法登录而没有错误消息然后我查看了由app/logs
dir中的symfony生成的日志
用户已成功通过身份验证
然后重定向到仪表板,但从仪表板重定向生成的日志
访问被拒绝(用户未完全通过身份验证)
原因是会话数据在会话表中被截断,所以我也改变了我的会话表,这就完成了工作
ALTER TABLE `session` CHANGE `session_value` `session_value` LONGTEXT NOT NULL;
ALTER TABLE `session`
ENGINE=INNODB
ROW_FORMAT=COMPRESSED
KEY_BLOCK_SIZE=8;
我还更新了my.ini
文件,并将文件格式更改为Barracuda,默认文件格式为antelop
[mysqld]
innodb_file_per_table
innodb_file_format = Barracuda