I have a class UserMapper
<?php
namespace Models;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use \PDO;
class UserMapper implements UserProviderInterface
{
/**
* Database connection.
*/
var $db = NULL;
/**
* Constructor function. Loads model from database if the id is known.
*
* @param $db
* Database connection
*/
function __construct() {
$this->db = ConnectionProvider::getConnection();
}
function save(User $user) {
$statement = $this->db->prepare('INSERT INTO user (username, password, salt, roles) VALUES (:username, :password, :salt, :roles)');
foreach (array('username', 'password', 'salt', 'roles') as $property) {
$placeholders[':' . $property] = $user->get($property);
}
$isOk = $statement->execute($placeholders);
return $isOk;
}
public function findByUsername($username) {
$statement = $this->db->prepare('SELECT * FROM user WHERE username = :username');
$statement->execute(array(':username' => $username));
$data = $statement->fetch(PDO::FETCH_ASSOC);
if($data['username'] == null)
return null;
else {
$user = new User($data['username'], $data['salt'], $data['roles']);
$user->set('password', $data['password']);
return $user;
}
}
function loadAll() {
// Query for the existing users.
$statement = $this->db->query('SELECT * FROM user');
$results = $statement->fetchAll(PDO::FETCH_ASSOC);
// Format the list and output it as JSON.
$data = array();
foreach ($results as $result) {
$user = new User($result['username'], $result['salt'], $result['roles']);
$user->set('passwort', $result['password']);
$data[] = $user;
}
return $data;
}
/**
* Delete this user.
*/
function delete(User $user) {
if ($user->get('username')) {
// Execute the delete query.
$statement = $this->db->prepare('DELETE FROM user WHERE username = :username');
$statement->execute(array(':username' => $user->get('username')));
}
}
/// UserProviderInterface
public function loadUserByUsername($username)
{
$user = $this->findByUsername($username);
if($user == null)
throw new UsernameNotFoundException(sprintf('Username "%s" does not exist.', $username));
return $user;
}
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 === 'Models\User';
}
}
and my class User
<?php
namespace Models;
use Symfony\Component\Security\Core\User\UserInterface;
class User implements UserInterface{
var $username = NULL;
var $password = NULL;
var $salt = NULL;
var $roles = NULL;
function __construct($username, $password, $sal, $roles) {
$this->username = $username;
$this->password = $password;
$this->salt = $salt;
$this->roles = $roles;
}
function getUsername() {
return $this->username;
}
function getRoles() {
return $this->salt;
}
function getSalt() {
return $this->roles;
}
function getPassword() {
return $this->password;
}
function eraseCredentials() {
}
function get($property) {
if (!empty($this->{$property})) {
return $this->{$property};
}
else {
return false;
}
}
function set($property, $value) {
$this->{$property} = $value;
}
function getAll() {
return array(
'username' => $this->get('username'),
'password' => $this->get('password'),
'salt' => $this->get('salt'),
'roles' => $this->get('roles')
);
}
}
And in my index.php
I configure the security context like this :
$app['security.firewalls'] = array(
'secured' => array(
'pattern' => '^/',
'anonymous' => array(),
'form' => array(
'login_path' => 'login',
'check_path' => 'login_check'
),
'users' => $app->share(function () use ($app) {
return $app['UserMapper'];
}),
)
);
$app['security.access_control'] = array(
array('path' => '^/login', 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY'),
array('path' => '^/', 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY'),
array('path' => '^/comment', 'methode' => 'POST', 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY'),
array('path' => '^/comment', 'methode' => 'DELETE', 'role' => 'ROLE_ADMIN'),
array('path' => '^/location', 'methode' => 'GET, POST', 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY'),
array('path' => '^/location', 'methode' => 'PUT, DELETE', 'role' => 'ROLE_ADMIN')
);
$app['security.provider'] = array(
'users' => array(
'entity' => array('class' => 'Models\User', 'property' => 'username')
)
);
$app['security.encoders'] = array(
'Models\User' => array(
'algorithm' => 'bcrypt',
)
);
$app->register(new UrlGeneratorServiceProvider());
$app->register(new Silex\Provider\SecurityServiceProvider(), array(
'security.firewalls' => $app['security.firewalls'],
'security.access_control' => $app['security.access_control'],
'security.provider' => $app['security.provider'],
'security.encoders' => $app['security.encoders'],
));
The problem is when I submit the login form with a foo login and foo password which don't exist in the database, the security context create me a session.
What is wrong with the security provider ?