2013-02-05 13 views
8

Sto sviluppando un'applicazione Silex e ora sono in fase di sicurezza. Ho letto tutta la documentazione che ho trovato in rete su questo argomento, ma ho molti dubbi e vorrei che qualcuno mi aiutasse, se possibile.Autenticazione utente con UserProvider con backb db in Silex

Fondamentalmente ho seguito this tutorial from Johann Reinke.

e naturalmente il Silex documentation:

anche tutto quello che ho trovato su Google.

Ma ancora, penso che Silex manchi ancora di molta documentazione, mi sono perso in molti modi.

Il mio codice:

$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'), 
), 
))); 

Ho tanti dubbi nel controller:

$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'); 

Questa è la mia classe, Provider User:

// 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'; 
} 
} 

E il mio modulo:

<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> 

E questo è il mio tavolo 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) 

ottengo sempre un "cattivo credenziali" risposta quando tentativo di login. Qualche idea? Grazie e grazie!

+1

Il primo collegamento sopra è rotto o contiene un virus (il mio firefox è appena diventato berserk). Puoi portarlo giù? – Dwebtron

risposta

4

A 40 caratteri, il campo password "pass" sta probabilmente troncando le password crittografate. Prova a cambiare il campo in varchar (255)

0

Ho avuto un problema simile utilizzando il codificatore predefinito, che sospetto fosse correlato al confronto dei database o forse alle codifiche multiple64 base.

L'ho sostituito con semplice sha1, abbastanza insicuro, ma questo dà un'idea generale (è possibile sostituirlo con sha2 per essere sicuri). Aggiungere questo dopo aver registrato il vostro fornitore di sicurezza:

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

E si dovrà assicurarsi che le password memorizzate utilizzano lo stesso algoritmo di hash.

Problemi correlati