2013-02-05 10 views
8

私はSilexアプリケーションを開発しています。今はセキュリティフェーズに入っています。私はこのテーマについてネット上で見つけたすべてのドキュメントを読んだことがありますが、私は多くの疑問があり、可能ならば誰かが私を助けてくれることを願っています。SilexでdbにバックアップされたUserProviderによるユーザ認証

基本的に私はthis tutorial from Johann Reinkeに従った。自然Silex documentation

:私は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) 

ときの試みのログイン、私はいつも「悪い資格証明書」の応答を取得。何か案は?感謝と乾杯!

+1

上記の最初のリンクは壊れているか、ウイルスを含んでいます(私のファイアフォックスは凶暴になりました)。あなたはそれを取ることができますか? – Dwebtron

答えて

4

40文字で、パスワードフィールド "pass"はおそらく暗号化されたパスワードを切り捨てています。フィールドをvarchar(255)に変更してみてください

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); 
}); 

また、保存されたパスワードが同じハッシュアルゴリズムを使用していることを確認する必要があります。

関連する問題