Este foro ya no está activo, así que no puedes publicar nuevas preguntas ni responder a las preguntas existentes.

Silex - No me permite hacer login

13 de enero de 2016

Hola,

Tenemos un proyecto con Silex, mi compañero ha estado trabajando en el y al yo retomar el proyecto pues se hizo el commit y yo me lo actualicé pero a mi no me funcionaba. Subimos incluso los vendors al repositorio y aun así no me funcionaba.

Total que al final decidí hacer un composer update ya que había instalado nuevas dependencias y estaba muy desactualizado (Symfony 2.3...). En resumen, que actualicé, hice algunos cambios para que se viese bien (los formularios de Bootstrap) y funcionaba todo correcto.

Pues hoy ha vuelto a hacer un commit solo de unos pocos archivos que había cambiado y que necesitaba y vuelve a no funcionar. He borrado incluso los vendors y hecho un composer install para dejarlo como si me hubiese montado el proyecto de nuevo. Pues nada.

El problema es que me muestra la pantalla de login (/login), relleno el formulario y en la acción de login (/login_check) me muestra Not allowed, nada mas. En el silex_dev.log me muestra lo siguiente:

[2016-01-13 12:38:31] myapp.INFO: Matched route "_wdt". {"route_parameters":{"_controller":"web_profiler.controller.profiler:toolbarAction","token":"ebbf67","_route":"_wdt"},"request_uri":"http://dev.beyondgame/_profiler/wdt/ebbf67"} []
[2016-01-13 12:38:31] myapp.INFO: Populated the TokenStorage with an anonymous Token. [] []
[2016-01-13 12:38:31] myapp.DEBUG: Access denied, the user is not fully authenticated; redirecting to authentication entry point. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException(code: 403): Access Denied. at C:\\xampp\\htdocs\\beyondgame\\vendor\\symfony\\security\\Http\\Firewall\\AccessListener.php:70)"} []
[2016-01-13 12:38:31] myapp.DEBUG: Calling Authentication entry point. [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.exception" to listener "Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelException". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.exception" to listener "Symfony\Component\Security\Http\Firewall\ExceptionListener::onKernelException". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Listener "Symfony\Component\Security\Http\Firewall\ExceptionListener::onKernelException" stopped propagation of the event "kernel.exception". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Listener "Silex\EventListener\LogListener::onKernelException" was not called for event "kernel.exception". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Listener "Silex\ExceptionListenerWrapper::__invoke" was not called for event "kernel.exception". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Listener "Silex\ExceptionListenerWrapper::__invoke" was not called for event "kernel.exception". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Listener "Silex\ExceptionHandler::onSilexError" was not called for event "kernel.exception". [] []
[2016-01-13 12:38:31] myapp.INFO: < 302 http://dev.beyondgame/login [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.response" to listener "Silex\EventListener\MiddlewareListener::onKernelResponse". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.response" to listener "Symfony\Component\HttpKernel\EventListener\ResponseListener::onKernelResponse". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.response" to listener "closure". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.response" to listener "Silex\EventListener\LogListener::onKernelResponse". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.response" to listener "Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelResponse". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.response" to listener "Symfony\Bundle\WebProfilerBundle\EventListener\WebDebugToolbarListener::onKernelResponse". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.finish_request" to listener "Symfony\Component\HttpKernel\EventListener\RouterListener::onKernelFinishRequest". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.finish_request" to listener "Silex\EventListener\LocaleListener::onKernelFinishRequest". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.finish_request" to listener "Symfony\Component\Security\Http\Firewall::onKernelFinishRequest". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.terminate" to listener "closure". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.terminate" to listener "closure". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.terminate" to listener "Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelTerminate". [] []
[2016-01-13 12:38:31] myapp.INFO: Matched route "login". {"route_parameters":{"_controller":"[object] (Closure: {})","_route":"login"},"request_uri":"http://dev.beyondgame/login"} []
[2016-01-13 12:38:31] myapp.INFO: Populated the TokenStorage with an anonymous Token. [] []
[2016-01-13 12:38:31] myapp.INFO: > GET /login [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelRequest". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.request" to listener "Silex\Provider\SessionServiceProvider::onEarlyKernelRequest". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\FragmentListener::onKernelRequest". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\RouterListener::onKernelRequest". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.request" to listener "Silex\EventListener\LocaleListener::onKernelRequest". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.request" to listener "Symfony\Component\Security\Http\Firewall::onKernelRequest". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.request" to listener "closure". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.request" to listener "Silex\EventListener\LogListener::onKernelRequest". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.request" to listener "Silex\EventListener\MiddlewareListener::onKernelRequest". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.controller" to listener "Silex\EventListener\ConverterListener::onKernelController". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.controller" to listener "Symfony\Component\HttpKernel\DataCollector\RequestDataCollector::onKernelController". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.view" to listener "Silex\EventListener\StringToResponseListener::onKernelView". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Listener "Silex\EventListener\StringToResponseListener::onKernelView" stopped propagation of the event "kernel.view". [] []
[2016-01-13 12:38:31] myapp.INFO: < 200 [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.response" to listener "Silex\EventListener\MiddlewareListener::onKernelResponse". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.response" to listener "Symfony\Component\HttpKernel\EventListener\ResponseListener::onKernelResponse". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.response" to listener "closure". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.response" to listener "Silex\EventListener\LogListener::onKernelResponse". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.response" to listener "Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelResponse". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.response" to listener "Symfony\Bundle\WebProfilerBundle\EventListener\WebDebugToolbarListener::onKernelResponse". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.finish_request" to listener "Symfony\Component\HttpKernel\EventListener\RouterListener::onKernelFinishRequest". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.finish_request" to listener "Silex\EventListener\LocaleListener::onKernelFinishRequest". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.finish_request" to listener "Symfony\Component\Security\Http\Firewall::onKernelFinishRequest". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.terminate" to listener "closure". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.terminate" to listener "closure". [] []
[2016-01-13 12:38:31] myapp.DEBUG: Notified event "kernel.terminate" to listener "Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelTerminate". [] []

El proyecto se inicio hace un par de años con Silex 1.1, usando el Silex Skeleton de Fabien y la verdad que las dependencias se han actualizado poco, más bien nada.

Comentar también que después de que me volviese a fallar a mi, hice que mi compañero borrase los vendors y después un composer install, ambos teniendo el mismo composer.json y composer.lock. A el tampoco le funciona ahora.

He visto que ha cambiado el SecurityServiceProvider y que estaba usando $app['security'] para obtener el token o comprobar los roles y ya no se usa, pero lo he ido cambiando en lo que podría afectar al login. A ver si sabéis que puede ser, a las malas tendré que volver a una versión pre actualización.

Gracias.

Un saludo.


Respuestas

#1

Leyendo los logs, el error lo interpreto de la siguiente manera:

  1. Quieres entrar a una zona que está restringida.
  2. Symfony se da cuenta que eres un usuario anónimo y por tanto va a redirigirte a otro sitio para que te puedas "loguear" (supongo que será un formulario de login).
  3. El error se produce al intentar acceder a ese formulario de login. ¿El motivo? Parece que el acceso al propio formulario está protegido por seguridad.

Si esto es así, tranquilo porque es un error típico en las aplicaciones Symfony: se te olvida permitir el acceso al formulario de login y entonces entras en un bucle infinito (para poder loguearte, tienes que estar logueado).

Si por ejemplo tenéis esta configuración:

$app['security.access_rules'] = array(
    array('^/admin', 'ROLE_ADMIN'),
);

Habría que usar algo así (el orden importa, así que hay que poner primero la ruta del login):

$app['security.access_rules'] = array(
    array('^/admin/login', 'IS_AUTHENTICATED_ANONYMOUSLY'),
    array('^/admin', 'ROLE_ADMIN'),
);

Además, el firewall que protege la aplicación debe permitir el acceso a los usuarios anónimos (tranquilo: solo podrán acceder a las páginas no protegidas). Puedes añadir

$app['security.firewalls'] = array(
    'main' => array(
        'anonymous' => true,
 
        // ...
    ),
);

Si lo prefieres, puedes crear un firewall solamente para permitir el acceso de usuarios anónimos al formulario de login:

$app['security.firewalls'] = array(
    'login_firewall' => array(
        'pattern' => '^/admin/login',
        'anonymous' => true,
    ),
 
    'main' => array(
        // ...
    ),
);

@javiereguiluz

13 enero 2016, 13:32
#2

Gracias por responder, pero todo lo que me comentas ya lo tengo desde los inicios del proyecto jeje. Esto es lo que tengo, para que te hagas una idea:

$app['security.firewalls'] = array(
    'default' => array(
        'pattern' => '^/',
        'anonymous' => true,
        'form' => array(
            'login_path' => '/login',
            'check_path' => '/login_check',
            'default_target_path' => '/inicio',
            'always_use_default_target_path' => true,
            'use_referer' => true
        ),
        'logout' => array(
            'logout_path' => '/logout'
        ),
        'users' => $app->share(function () use ($app) {
            return new UserProvider($app['db'], $app['request_stack']);
        }),
    )
);
 
$app['security.role_hierarchy'] = array(
    'ROLE_ADMIN'        => array('ROLE_USER'),
    'ROLE_SUPER_ADMIN'  => array('ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH'),
);
 
$app['security.access_rules'] = array(
    array('^/login',        'IS_AUTHENTICATED_ANONYMOUSLY'),
    array('^/recover',      'IS_AUTHENTICATED_ANONYMOUSLY'),
    array('^/login_check',  'IS_AUTHENTICATED_ANONYMOUSLY'),
    array('^/api',          'IS_AUTHENTICATED_ANONYMOUSLY'),
    array('^/cron',         'IS_AUTHENTICATED_ANONYMOUSLY'),
    array('^/admin',        'ROLE_ADMIN'),
    array('^/',             'ROLE_USER'),
);

Toda la aplicación necesita estar logueado, solo que la parte de /admin es para los administradores. En efecto cuando entras en /, automáticamente redirijo a /login o si entras en una zona restringida te redirige al login. Realmente la ruta principal es /inicio, no se usa /.

Los problemas han venido al actualizar los vendors, te pego mi composer.json:

{
    "name": "fabpot/silex-skeleton",
    "description": "A pre-configured skeleton for the Silex microframework",
    "license": "MIT",
    "type": "project",
    "require": {
        "php": ">=5.3.3",
        "silex/silex": "~1.0",
        "swiftmailer/swiftmailer": "v5.0.3",
        "silex/web-profiler": "~1.0",
        "symfony/browser-kit": "~2.3",
        "symfony/class-loader": "~2.3",
        "symfony/config": "~2.3",
        "symfony/console": "~2.3",
        "symfony/css-selector": "~2.3",
        "symfony/debug": "~2.3",
        "symfony/finder": "~2.3",
        "symfony/form": "~2.3",
        "symfony/monolog-bridge": "~2.3",
        "symfony/process": "~2.3",
        "symfony/security": "~2.3",
        "symfony/translation": "~2.3",
        "symfony/twig-bridge": "~2.3",
        "symfony/validator": "~2.3",
        "doctrine/dbal": "~2.3",
        "phpoffice/phpexcel": "~1.0",
        "imagine/imagine": "0.6.3",
        "gomoob/php-pushwoosh": "^1.0",
        "asm89/stack-cors": "^0.2.1",
        "stack/builder": "^1.0"
    },
    "require-dev": {
        "raulfraile/ladybug-bundle": "~1.0",
        "sorien/silex-pimple-dumper": "~1.0"
    },
    "autoload": {
        "psr-0": { "": "src/" }
    },
    "extra": {
        "branch-alias": {
            "dev-master": "1.3.x-dev"
        }
    }
}

Gracias.

Un saludo.

@LoGaNsF

13 enero 2016, 13:41
#3

Olvida mi respuesta anterior porque creo que he interpretado mal los logs. Lo que yo pensaba que un error, en realidad es algo normal: se notifica un error 403 porque eres anónimo y quieres acceder a una zona protegida. Si sigues leyendo los logs, se ve que la página de login se renderiza bien y el resultado es un HTTP 200.

Pero leyendo de nuevo tu mensaje original, veo que dices que la respuesta es un Not Allowed en el /login_check. Si esto se refiere al código de estado HTTP 405, entonces el problema es que el navegador ha hecho una petición con un método HTTP (será POST en este caso) que no está permitido por la aplicación.

Lo extraño es que para el login_check normalmente se define solo la ruta, ya que Symfony se encarga de procesarlo. ¿Puedes comprobar si tienes un controlador propio para el login_check? Si es así, ¿está definido con $app->get() o con $app->post() o $app->match()?

@javiereguiluz

13 enero 2016, 14:36
#4

Ya esta "solucionado". Parece un problema del navegador (Chrome) o de la cache de este, aunque la borras y sigue igual. Resulta que con Firefox va perfecto, pero como ambos usamos Chrome pues nos fallaba. De todas formas, lo de Not allowed es el mensaje que me sale en la pantalla y mirando en network el código es 403. Vamos, que relleno el formulario, lo envío y me va a /login_check y ahí se queda con el mensaje Not allowed.

No es un controlador propio el de login_check y la peticion es POST.

No creo que sea un problema de incompatibilidad con este navegador, ¿no?.

Gracias por la ayuda.

Un saludo.

@LoGaNsF

13 enero 2016, 15:39
#5

Yo uso Chrome habitualmente y no me he encontrado este error. Tampoco me suena haber leído nada parecido en los issues del repositorio. ¿Tenéis instalada alguna extensión "fuera de lo común" en el navegador? Lo digo porque si que me suenan algunos errores por ejemplo con el profiler de Symfony sufridos por gente que tenía instaladas algunas extensiones un poco raras en el navegador.

@javiereguiluz

13 enero 2016, 15:43
#6

Pues que yo sepa no tenemos ninguna fuera de lo normal, no tenemos las mismas pero si la mayoria en comun. Postman, Allow-Control-Allow-Origin (para lo CORS), Drive, Backbone Debugger, Pocket, PHP Ninja, Windows Resizer, Hangouts y otras típicas de Google como la de documentos, ademas de Mail Track y Dropbox (para Gmail). Funciona hasta en Internet Explorer. Hemos vaciado cache del navegador y nada, de echo la de Postman para hacer peticiones a la API del proyecto nos devuelve el "Not allowed".

¡SOLUCIONADO!

Resulta que usamos StackPHP con el middleware para los CORS y habíamos modificado la clase Cors.php del vendor directamente, concretamente el array de configuración por defecto. Pues como hemos borrado los vendors la configuración desapareció. Se ha configurado de nuevo (ahora en el index) y perfecto. También nos encontramos con que usaba la librería JWT pero no desde composer, simplemente un archivo que descargue en su día, y al pasar a utilizar la librería desde composer, pues también nos fallaba ya que la que usábamos estaba desactualizada.

Eso nos pasa por tocar donde no debemos, pero bueno, así es como se aprende.

@LoGaNsF

13 enero 2016, 16:01