我正在开发Silex应用程序,现在我处于安全阶段。我已经阅读了网上关于这个主题的所有文档,但我有很多疑问,如果可能的话,我希望有人能帮助我。
基本上我跟着this tutorial from Johann Reinke。
我在Google上发现的一切。
但是,我认为Silex仍然缺少大量文档,我在很多方面都迷失了。
我的代码:
$app->register(new Silex\Provider\SessionServiceProvider(), array(
'session.storage.save_path' => __DIR__.'/../vendor/sessions',
));
$app->register(new Silex\Provider\DoctrineServiceProvider(), array(
'db.options' => array(
'driver' => 'pdo_mysql',
'host' => 'localhost',
'dbname' => 'dbname',
'user' => 'someuser',
'password' => 'somepass',
'charset' => 'utf8',
),
));
$app['security.encoder.digest'] = $app->share(function ($app) {
return new MessageDigestPasswordEncoder('sha1', false, 1);
});
$app['security.firewalls'] = array(
'acceso' => array(
'pattern' => '^/confirmar',
'form' => array('login_path' => '/acceso', 'check_path' => '/confirmar/comprobar_acceso'),
'logout' => array('logout_path' => '/confirmar/salir'),
'users' => $app->share(function() use ($app) {
return new Acme\User\UserProvider($app['db']);
}),
),
);
$app->register(new Silex\Provider\SecurityServiceProvider(array(
'security.firewalls' => $app['security.firewalls'],
'security.access_rules' => array(
array('^/confirmar', 'ROLE_USER'),
),
)));
我对控制器有很多怀疑:
$app->match('/acceso', function(Request $request) use ($app) {
$username = $request->get('_username');
$password = $request->get('_password');
if ('POST' == $request->getMethod())
{
$user = new Acme\User\UserProvider($app['db']);
$encoder = $app['security.encoder_factory']->getEncoder($user);
// compute the encoded password
$encodedPassword = $encoder->encodePassword($password, $user->getSalt());
// compare passwords
if ($user->password == $encodedPassword)
{
// set security token into security
$token = new UsernamePasswordToken($user, $password, '', array('ROLE_USER'));
$app['security']->setToken($token);
//return $app->redirect('/jander');
// redirect or give response here
} else {
// error feedback
}
}
return $app['twig']->render('login.twig', array(
'error' => $app['security.last_error']($request),
'last_username' => $app['session']->get('_security.last_username'),
));
})
->bind('acceso');
这是我的班级,用户提供商:
// src/Acme/User/UserProvider.php
namespace Acme\User;
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;
use Doctrine\DBAL\Connection;
class UserProvider implements UserProviderInterface
{
private $conn;
public function __construct(Connection $conn)
{
$this->conn = $conn;
}
public function loadUserByUsername($username)
{
$stmt = $this->conn->executeQuery('SELECT * FROM compradores WHERE idemail = ?', array(strtolower($username)));
if (!$user = $stmt->fetch()) {
throw new UsernameNotFoundException(sprintf('Username "%s" does not exist.', $username));
}
return new User($user['idemail'], $user['pass'], explode(',', $user['roles']), true, true, true, true);
}
public function refreshUser(UserInterface $user)
{
if (!$user instanceof User) {
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));
}
return $this->loadUserByUsername($user->getUsername());
}
public function supportsClass($class)
{
return $class === 'Symfony\Component\Security\Core\User\User';
}
}
我的表格:
<form action="{{ path('confirmar_comprobar_acceso') }}" method="post">
{{ error }}
<input type="text" name="_username" value="{{ last_username }}" />
<input type="password" name="_password" value="" />
<input type="submit" />
</form>
这是我的mysql表:
id int(15)
idemail varchar(255)
nombre varchar(255)
apellidos varchar(255)
telefono int(11)
activo tinyint(4)
pass varchar(40)
roles varchar(255)
iva tinyint(4)
nifcif varchar(255)
尝试登录时,我总是收到“错误凭据”响应。有任何想法吗?谢谢,干杯!
答案 0 :(得分:4)
在40个字符处,您的密码字段“pass”可能会截断加密的密码。尝试将字段更改为varchar(255)
答案 1 :(得分:0)
我使用默认编码器时遇到了类似问题,我怀疑它与数据库整理有关,或者与多个base64编码有关。
我用简单的sha1替换它,相当不安全,但这给出了一个大概的想法(你可以用sha2替换它以保证安全)。注册安全提供程序后添加此项:
$app['security.encoder.digest'] = $app->share(function ($app) {
// use the sha1 algorithm
// don't base64 encode the password
// use only 1 iteration
return new MessageDigestPasswordEncoder('sha1', false, 1);
});
您必须确保存储的密码使用相同的散列算法。