i have been assigned task improve authentication system on symfony-based website. details don't matter, what's important new guard component (introduced in symfony 2.8) fitted task.
i have following problem: guard manage authenticate user & redirect homepage, access homepage refused (authenticationexpiredexception thrown) , user redirected login. user pov, seems login fail.
the problem appear simple project :
/* not writing getters, setters , annotations here readability */ class customuser implements userinterface, \serializable { private $id; protected $username; protected $salt; protected $password; public function __construct() { $this->salt = md5(uniqid(null, true)); } public function serialize() { return serialize(array($this->id,)); } public function unserialize($serialized) { list($this->id,) = unserialize($serialized); } }
the guard class:
class customguardauthenticator extends abstractguardauthenticator { private $container; private $router; public function __construct(containerinterface $container) { $this->container = $container; $this->router = $container->get('router'); } public function start(request $request, authenticationexception $authexception = null) { $response = new redirectresponse($this->router->generate('login')); return $response; } public function getcredentials(request $request) { if ($request->getpathinfo() != '/login_check' || !$request->ismethod('post')) { return null; } return array( 'username' => $request->request->get('_username'), 'password' => $request->request->get('_password'), ); } public function getuser($credentials, userproviderinterface $userprovider) { $user = $userprovider->loaduserbyusername($credentials['username']); /* no problem here, user correctly fetched */ return $user; } public function checkcredentials($credentials, userinterface $user) { $encoder = $this->container->get('security.password_encoder'); if (!$encoder->ispasswordvalid($user, $credentials['password'])) { /* no problem here either */ throw new badcredentialsexception(); } return true; } public function onauthenticationfailure(request $request, authenticationexception $exception) { $response = new redirectresponse($this->router->generate('login')); return $response; } public function onauthenticationsuccess(request $request, tokeninterface $token, $providerkey) { /* debugging show reach */ return new redirectresponse($this->router->generate('homepage')); } public function supportsrememberme() { return false; } }
security.yml:
security: encoders: appbundle\entity\customuser: algorithm: sha1 encode_as_base64: false iterations: 1 providers: main: entity: {class: appbundle\entity\customuser, property: username} firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: pattern: ^/ anonymous: true guard: authenticators: - security.custom.guard access_control: - { path: ^/security/*, roles: is_authenticated_anonymously} - { path: ^/, roles: [role_user] }
- if user class not implements serializable, work.
- if user class implements equatableinterface checking id, work.
- if use equivalent authenticationprovider instead of guard, work.
i'd avoid having use 1 of 3 workarounds. of i'd understand problem, , not feel 2 last days wasted!
any appreciated :)
Comments
Post a Comment