Muy buenas, he seguido el tutorial completo de este magnifico portal. Me ha servido de mucho pero estoy atascado en el tema de los usuarios.
Utitilizo Silex-Skeleton en su versión mas reciente, además utilizo DoctrineORM para la base de datos.
He tenido que crear un UserProvider
, he comprobado que me llega bien el nombre de usuario y realiza la consulta perfectamente, así que creo que está todo bien aquí.
// Silex/Providers/UserProvider.php namespace Providers; 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\UnsupportedUserException; use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; class UserProvider implements UserProviderInterface { private $app; public function __construct(\Silex\Application $app) { $this->app = $app; } public function loadUserByUsername($username){ //print_r($username); $em = $this->app["orm.ems"]['local']; if($em instanceof \Doctrine\ORM\EntityManager){ if(!$user = $em->getRepository("Entity\User")->findOneBy(array("username"=>$username))){ throw new UsernameNotFoundException(sprintf('Username "%s" does not exist.', $username)); } } //print_r($user); die(); return $user; } public function refreshUser(UserInterface $user) { if (!$user instanceof \Entity\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 === '\Entity\User'; } }
Este es mi archivo app.php
, dispongo de dos bases de datos y también dispongo de dos tipos de ROLES.
El primer ROLE_ADMIN trae los usuarios del UserProvider
y es aquí donde falla. No loguea, no lo entiendo.
Por otro lado, mas abajo, en ROLE partner, obtengo el usuario y contraseña sin UserProvider y si que me loguea bien, por tanto, no entiendo que está pasando. Las contraseñas estan bien codificadas, he probado con todo y no doy con la solución. A ver si alguien puede exarme una mano. Un saludo y muchas gracias de antemano!!
use Silex\Application; use Silex\Provider\TwigServiceProvider; use Silex\Provider\ValidatorServiceProvider; use Silex\Provider\ServiceControllerServiceProvider; use Silex\Provider\HttpFragmentServiceProvider; use Dflydev\Provider\DoctrineOrm\DoctrineOrmServiceProvider; use Silex\Provider\DoctrineServiceProvider; //use Lib\Provider\UserProvider; use Silex\Provider\SecurityServiceProvider; //use Silex\Provider\UrlGeneratorServiceProvider; //obsoleto Silex V2.0 use Silex\Provider\RoutingServiceProvider; use Silex\Provider\SessionServiceProvider; use Symfony\Component\Routing\Generator\UrlGenerator; use Providers\UserProvider; use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder; $app = new Application(); $app->register(new RoutingServiceProvider()); $app->register(new Silex\Provider\RoutingServiceProvider()); $app->register(new ValidatorServiceProvider()); $app->register(new ServiceControllerServiceProvider()); $app->register(new TwigServiceProvider()); $app->register(new HttpFragmentServiceProvider()); $app['twig'] = $app->extend('twig', function ($twig, $app) { // add custom globals, filters, tags, ... $twig->addFunction(new \Twig_SimpleFunction('asset', function ($asset) use ($app) { return $app['request_stack']->getMasterRequest()->getBasepath().'/'.ltrim($asset, '/'); })); return $twig; }); /*======================= DOCTRINE ORM ========================== * * FUENTE: https://github.com/dflydev/dflydev-doctrine-orm-service-provider */ $app->register(new SessionServiceProvider()); $app->register(new Silex\Provider\DoctrineServiceProvider(), array( 'dbs.options' => array( 'local' => array( //base de datos local 'driver' => 'pdo_mysql', 'host' => 'localhost', 'dbname' => 'silex', 'user' => 'root', 'password' => '', 'charset' => 'utf8', 'driverOptions' => array(1002 => 'SET NAMES utf8'), ), 'remote' => array( //base de datos remota 'driver' => 'pdo_mysql', 'host' => '', 'dbname' => '', 'user' => '', 'password' => '', 'charset' => 'utf8', 'driverOptions' => array(1002 => 'SET NAMES utf8'), ), ), )); $app->register(new Dflydev\Provider\DoctrineOrm\DoctrineOrmServiceProvider(), array( "orm.ems.default" => "local", "orm.ems.options" => array( "local" => array( "connection" => "local", "mappings" => array( array( "type" => "yml", "namespace" => "Entity", "path" => realpath(__DIR__."/../config/doctrine"), ), ), ), "remote" => array( "connection" => "remote", "mappings" => array( array( "type" => "yml", "namespace" => "Entity", "path" => realpath(__DIR__."/../config/doctrine"), ), ), ), ), )); /*========================== USERS =============================*/ $app->register(new Silex\Provider\SecurityServiceProvider(), array( 'security.firewalls' => array( 'dev' => array( 'pattern' => '^/(_(profiler|wdt)|css|img|js)/', 'security' => false), //Reglas para el admin 'admin' => array( 'pattern' => '^/admin/panel', 'http' => true, 'form' => array( 'login_path' => '/admin', 'check_path' => '/admin/panel/login_check', 'default_target_path' => "/admin/panel", //url de redireccion 'always_use_default_target_path' => true, 'username_parameter' => '_username', 'password_parameter' => '_password' ), 'anonymous' => false , /*'users' => array( 'admin' => array('ROLE_ADMIN', '5FZ2Z8QIkA7UTZ4BYkoC+GsReLf569mSKDsfods6LYQ8t+a8EW9oaircfMpmaLbPBh4FOBiiFyLfuZmTSUwzZg=='), ),*/ 'users' => function ($app) { return new \Providers\UserProvider($app); }, 'logout' => array( 'logout_path' => '/admin/panel/logout'), 'invalidate_session' => false ), //Reglas para el partner 'partner' => array( 'pattern' => '^/partner', 'http' => true, 'form' => array( 'login_path' => '/', 'check_path' => '/partner/login_check', 'default_target_path' => "/partner", //url de redireccion 'always_use_default_target_path' => true, 'username_parameter' => '_username', 'password_parameter' => '_password' ), 'anonymous' => false , 'users' => array( 'partner' => array('ROLE_PARTNER', '5FZ2Z8.....4FOBiiFyLfuZmTSUwzZg=='), ), /*'users' => function ($app) { return new \Providers\UserProvider($app); },*/ 'logout' => array( 'logout_path' => '/partner/logout'), 'invalidate_session' => false ), ), 'security.encoders' => array( 'Entity\User'=> array( 'algorithm' => 'sha1', 'iterations' => 4, 'encode_as_base64' => false ) ) )); $app['user.options'] = array( //'templates' => array( // 'layout' => 'layout.twig', // 'view' => 'view.twig', //), 'mailer' => array('enabled' => false), 'userClass' => 'Entity\User', ); /*$app['security.role_hierarchy'] = array( 'ROLE_ADMIN' => array('ROLE_PARTNER', 'ROLE_ALLOWED_TO_SWITCH'), );*/ $app['security.access_rules'] = array( //Especificando los ROLES array('^/admin/panel', 'ROLE_ADMIN', 'http'), array('^/partner', 'ROLE_PARTNER','http'), ); return $app;
NOTA: En el UserProvider, he colocado un PRINT_R($user)
en la función LoadUserByUsername()
.El resultado es el siguiente:
Entity\User Object ( [id_user:Entity\User:private] => 1 [username:Entity\User:private] => admin2 [email:Entity\User:private] => [email protected] [password:Entity\User:private] => 5FZ2Z8QIkA7UTZ4BYkoC+.......== [roles:Entity\User:private] => ROLE_ADMIN )
Entiendo, que ha realizado la consulta a la base de datos a través de la entidad USER
, ha buscado por el usuario ADMIN2
y lo ha encontrado y por ende saca la CONTRASEÑA y el ROLE. Hasta aquí puede que todo OK
peeeero...cuando hace el return ya a partir de ahí...no funciona.
Igual esto puede ayudar un poco, no se si lo que devuelve esta bien...porque como no funciona...pues no se qué pensar, estoy empezando con Silex y Doctrine y estoy aprediendo aún. Un saludo!!
Respuestas
Hola, podrías intentar con algo así
... 'admin' => array( 'pattern' => '^/admin', 'anonymous' => true, 'form' => array( 'login_path' => '/admin/login', 'check_path' => '/admin/login_check', 'default_target_path' => '/admin/panel', 'always_use_default_target_path' => true, ), 'logout' => array( 'logout_path' => '/admin/logout', 'target_url' => '/admin', ), 'users' => function ($app) { return new \Providers\UserProvider($app); }, ), // ... $app['security.access_rules'] = array( array( '^/admin/login', 'IS_AUTHENTICATED_ANONYMOUSLY', ), array( '^/admin*', 'ROLE_ADMIN', ), array( '^/partner', 'ROLE_PARTNER', ), );
Saludos.
@iBet7o
Muchas gracias @iBet7o.
He realizado los cambios que me dices y nada, sigue igual, a ti te funciona bien tu código?? utilizas DoctrineORM ??
Un saludo!
@daviz_xtr
ya esta solucionado, por si alguno le pasa y le puede ayudar.
Se me olvido implementar UserInterface en Entity/User.
<?php namespace Entity; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Security\Core\User\UserInterface; /** * User * * @ORM\Table(name="user") * @ORM\Entity */ class User implements UserInterface {
Ademas me daba errores con los ROLES, la solucion ha sido colocar:
/** * Get roles * * @return string */ public function getRoles() { return array($this->roles); }
@daviz_xtr
ya esta solucionado, por si alguno le pasa y le puede ayudar.
Se me olvido implementar UserInterface en Entity/User.
<?php namespace Entity; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Security\Core\User\UserInterface; /** * User * * @ORM\Table(name="user") * @ORM\Entity */ class User implements UserInterface {
Ademas me daba errores con los ROLES, la solucion ha sido colocar:
/** * Get roles * * @return string */ public function getRoles() { return array($this->roles); }
@daviz_xtr
ya esta solucionado, por si alguno le pasa y le puede ayudar.
Se me olvido implementar UserInterface en Entity/User.
<?php namespace Entity; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Security\Core\User\UserInterface; /** * User * * @ORM\Table(name="user") * @ORM\Entity */ class User implements UserInterface { //...
Ademas me daba errores con los ROLES, la solucion ha sido colocar:
//... /** * Get roles * * @return string */ public function getRoles() { return array($this->roles); } //...
Con estos cambios ya funciona correctamente SILEX con DoctrineORM.
@daviz_xtr