php - Silex, bad credentials with security firewalls and custom user provider -
i have bad credentials on login attempt security firewalls , custom user provider. here's code.
$app->register(new securityserviceprovider(), array( 'security.firewalls' => array( 'admin' => array( 'pattern' => '^/admin', 'form' => array('login_path' => '/login', 'check_path' => '/admin/login_check'), 'logout' => array('logout_path' => '/admin/logout'), // url call logging out 'users' => $app->share(function() use ($app) { // specific class user\userprovider return new userprovider(); }), ) ), 'security.access_rules' => array( // can rename role_admin wish array('^/admin', 'role_admin'), ) )); $app['security.encoder.digest'] = $app->share(function ($app) { // use sha1 algorithm // don't base64 encode password // use 1 iteration return new messagedigestpasswordencoder('sha1', false, 1); });
my route :
$app->get("/login", "site\controllers\sitecontroller::login"); $app->post("/admin/login_check", "admin\controllers\admincontroller::logincheck");
my sitecontroller function :
public function login(application $app, request $request) { return $app['twig']->render('site/views/login.html.twig', array( 'error' => $app['security.last_error']($request), 'last_username' => $app['session']->get('_security.last_username'), )); }
my view :
<form action="{{ path('admin_login_check') }}" method="post"> {{ error }} <input type="text" name="username" value="{{ last_username }}" /> <input type="password" name="password" value="" /> <input type="submit" /> </form>
my db table :
id username password roles 1 admin d033e22ae348aeb5660fc2140aec35850c4da997 role_admin
my custom user provider :
<?php namespace user\models; use app\config\pdofactory; use symfony\component\security\core\user\userproviderinterface; use symfony\component\security\core\user\userinterface; use symfony\component\security\core\user\user; use symfony\component\security\core\exception\usernamenotfoundexception; use symfony\component\security\core\exception\unsupporteduserexception; class userprovider extends pdofactory implements userproviderinterface { public function loaduserbyusername($username) { $response = $this->db->prepare('select * users username = ?'); $response->execute(array(strtolower($username))); if (!$user = $response->fetch()) { throw new usernamenotfoundexception(sprintf('username "%s" not exist.', $username)); } return new user($user['username'], $user['password'], explode(',', $user['roles']), true, true, true, true); } public function refreshuser(userinterface $user) { if (!$user instanceof user) { throw new unsupporteduserexception(sprintf('instances of "%s" not supported.', get_class($user))); } return $this->loaduserbyusername($user->getusername()); } public function supportsclass($class) { return $class === 'symfony\component\security\core\user\user'; } }
my database connection :
namespace app\config; abstract class pdofactory { protected $db; public function __construct() { $db = new \pdo('mysql:host=localhost;dbname=silex', 'root', ''); $db->setattribute(\pdo::attr_errmode, \pdo::errmode_exception); $this->db = $db; } }
on login attempt, don't think access logincheck function admincontroller since doesn't echo anything:
public function logincheck(application $app, request $request) { echo 'login-check'; $username = $request->get('username'); $password = $request->get('password'); $password = $app['security.encoder.digest']->encodepassword($password, ''); $userprovider = new userprovider(); $user = $userprovider->loaduserbyusername($username); if ($user->getpassword() == $password){ return $app['twig']->render('admin/views/index.html.twig'); } else{ return $app['twig']->render('site/views/login.html.twig', array( 'error' => $app['security.last_error']($request), 'last_username' => $app['session']->get('_security.last_username'), )); } }
my password 'admin', used code generate database table:
echo $app['security.encoder.digest']->encodepassword('admin', '');
can tell me wrong?
edit : mistake on view, didn't use underscore before post names
<form action="{{ path('admin_login_check') }}" method="post"> {{ error }} <input type="text" name="_username" value="{{ last_username }}" /> <input type="password" name="_password" value="" /> <input type="submit" /> </form>
and don't need route nor controller function login_check path. it's managed security firewalls. thank you help!
first of all, enable logging (via monolog provider , set $app['debug'] = true;
, check logs, security component yells lots of information if logged enabled.
second, don't have create controller (not route, security provider does you) check_path, the kernel traps incoming request path , checks if credentials valid (as long don't overwrite default authentication provider, don't want go route using login form).
having said , debug code can try use plain password encoder , once working, change again (you'll need update password field on db table, of course), log tell happening (if still lost log, post also).
Comments
Post a Comment