Foros del Web » Programando para Internet » PHP » Symfony »

[SOLUCIONADO] Seguridad: Creando un login con tabla User

Estas en el tema de Seguridad: Creando un login con tabla User en el foro de Symfony en Foros del Web. Buenas de nuevo. Ya tengo mas o menos encaminada la practica. Esta empezó gestionando una tabla de usuarios(User), mas adelante se relaciono con otras tablas, ...
  #1 (permalink)  
Antiguo 17/04/2016, 10:14
 
Fecha de Ingreso: enero-2016
Mensajes: 15
Antigüedad: 8 años, 2 meses
Puntos: 0
Seguridad: Creando un login con tabla User

Buenas de nuevo.
Ya tengo mas o menos encaminada la practica.
Esta empezó gestionando una tabla de usuarios(User), mas adelante se relaciono con otras tablas, las cuales también se gestionaban, ampliándose el proyecto, poco a poco.
Quiero cerrarlo con la gestión de usuarios y sesiones. En principio, por ahora, solo quería que se loguearan los administradores, en todas las direcciones.
He probado como 5 login distintos y ya no me aclaro.
La configuración de los ficheros es:

security.yml
Código PHP:
# To get started with security, check out the documentation:
# http://symfony.com/doc/current/book/security.html
security:

    
# http://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers
    
providers:
        
in_memory:
            
memory: ~
        
main:
            
entity: { class: inventariouserBundleEntityUserpropertyusername }

    
firewalls:
        
# disables authentication for assets and the profiler, adapt it according to your needs
        
dev:
            
pattern: ^/(_(profiler|wdt)|css|images|js)/
            
securityfalse
        login
:
            
pattern:  ^/login$
            
securityfalse    
            
        secured_area
:
            
pattern:    ^/
            
anonymous:  ~
            
form_login:
                
login_path:  user_login
                check_path
:  user_login
            logout
:
                
pathuser_logout
                target
: /
       
            
# activate different ways to authenticate

            # http_basic: ~
            # http://symfony.com/doc/current/book/security.html#a-configuring-how-your-users-will-authenticate

            # form_login: ~
            # http://symfony.com/doc/current/cookbook/security/form_login_setup.html


    
providers:
        
our_db_provider:
            
entity:
                class: 
userBundle:User
                property
username
                
# if you're using multiple entity managers
                # manager_name: customer
    

    
firewalls:
        
main:
            
pattern:    ^/
            
http_basic: ~
            
providerour_db_provider

    access_control
:
        - { 
path: ^/loginrolesIS_AUTHENTICATED_ANONYMOUSLY }
        - { 
path: ^/, rolesROLE_ADMIN }            
        
    
encoders:
        
inventariouserBundleEntityUser:
            
algorithmbcrypt
            cost
12 
routing.yml

Código PHP:
user_homepage:
    
path:     /
    
defaults: { _controlleruserBundle:Default:login}
user_login:
    
path:     /login
    defaults
: { _controlleruserBundle:Default:login }
user_check:
    
path:     /check

user_logout
:
    
path:     /logout
    defaults
: { _controlleruserBundle:Default:logout }
user_prueba:
    
path:     /prueba
    defaults
: { _controlleruserBundle:Default:prueba }
user_index:
    
path:       /user/index
    defaults
: { _controlleruserBundle:User:index }
user_add:
    
path:     /user/add
    defaults
: { _controlleruserBundle:User:add }
    
user_create:
..................... 
login.html.twig

Código PHP:
{% extends '::frontend.html.twig' %}
{% 
block body %}
{% for 
flashMessage in app.session.flashbag.get('mensaje') %}
<
span class="alert-success">
       {{ 
flashMessage }}
      <
hr />
</
span>
{% endfor %}
<
div class="row">
<
div class="col-sm-4"></div>
<
div class="col-sm-4">    
<
h1>Ingrese sus datos</h1>
</
div>
<
div class="col-sm-4"></div>
</
div>



 <
form class="form-horizontal" role="form" method="POST" action="{{path('user_check')}}">
<
div class="row">
<
div class="col-sm-4"></div>
            <
div class="form-group">
            <
label for="inputEmail3" class="col-sm-1 control-label">{{'Username'|trans}}</label>
            <
div class="col-sm-3">
                        <
input type="text" name="_username" class="form-control" id="inputEmail3" value="{{ last_username }}" />
  />
            </
div>
            </
div>
</
div>
<
div class="row">
<
div class="col-sm-4"></div
    <
div class="form-group">
      <
label for="inputPassword3" class="col-sm-1 control-label">Password</label>
      <
div class="col-sm-3">
        <
input type="password" name="_password" class="form-control" id="inputPassword3" placeholder="Password" />
      </
div>
    </
div>
</
div>         
<
div class="row">
<
div class="col-sm-4"></div>         
    <
div class="form-group">
      <
div class="col-sm-3">
        <
button type="submit" class="btn btn-default">{{'Sign in'|trans}}</button>
      </
div>
    </
div>
  </
form>
<
div class="col-sm-4"></div>
</
div>
   {% 
endblock %} 
DefaultController.php

Código PHP:
<?php

namespace inventariouserBundleController
;

use 
SymfonyBundleFrameworkBundleControllerController;
use 
SymfonyComponentHttpFoundationRequest;
use 
SymfonyComponentSecurityCoreSecurityContext;
use 
SymfonyComponentSecurityCoreExceptionAuthenticationException;
use 
SymfonyComponentDependencyInjectionContainerAware;
use 
SymfonyBridgeDoctrineFormTypeEntityType;
use 
inventariouserBundleEntityUser;
use 
inventariouserBundleFormUserType;
use 
DoctrineORMEntityRepository;
use 
SymfonyComponentFormAbstractType;
use 
SymfonyComponentFormFormBuilder;
use 
SymfonyComponentFormExtensionCoreTypeTextType;
use 
SymfonyComponentFormExtensionCoreTypeChoiceType;
use 
SymfonyComponentFormExtensionCoreTypeButtonType;



class 
DefaultController extends Controller
{
   
  public function 
loginAction()
    {
        
$request $this->getRequest();
        
$session $request->getSession();

        
// get the login error if there is one
        
if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
            
$error $request->attributes->get(
                
SecurityContext::AUTHENTICATION_ERROR
            
);
        } else {
            
$error $session->get(SecurityContext::AUTHENTICATION_ERROR);
            
$session->remove(SecurityContext::AUTHENTICATION_ERROR);
        }

        return 
$this->render(
            
'userBundle:Default:login.html.twig',
            array(
                
// last username entered by the user
                
'last_username' => $session->get(SecurityContext::LAST_USERNAME),
                
'error'         => $error,
            )
        );
    }
    public function 
checkAction()
    {
        throw new 
RuntimeException('You must configure the check path to be handled by the firewall using form_login in your security firewall configuration.');
    }
............
Hay mucho código que debe sobrar de hacer pruebas.
Cuando ejecuto el programa se va al login y aparece

UndefinedMethodException in DefaultController.php line 49:
Attempted to call an undefined method named "getRequest" of class "inventario\userBundle\Controller\DefaultControlle r".

De alguna forma es lógico porque el objeto todavía no se ha creado, pero he visto montones de ejemplos y todos empiezan con:
Código PHP:
     $request $this->getRequest(); 
No comprendo cual es el procedimiento que hay entre security.yml y el controlador, ¿Que se tiene que ejecutar en medio? ¿Llama al login antes que al controlador y de esta manera ya esta creado Request?
¿Alguien tiene un ejemplo pequeño que funcione y que pueda ver?.
Saludos Luis.
  #2 (permalink)  
Antiguo 17/04/2016, 10:34
 
Fecha de Ingreso: enero-2016
Mensajes: 15
Antigüedad: 8 años, 2 meses
Puntos: 0
Respuesta: Seguridad: Creando un login con tabla User

Vaya se me olvido el gran User
Código PHP:
<?php

namespace inventariouserBundleEntity
;

use 
DoctrineORMMapping as ORM;
use 
SymfonyComponentSecurityCoreUserUserInterface;
use 
SymfonyComponentSecurityCoreUserAdvancedUserInterface;
/* esta linea es para validaciones*/
use SymfonyComponentValidatorConstraints as Assert;
/* esta linea es para que no haya valores repetidos en la tabla*/
use SymfonyBridgeDoctrineValidatorConstraintsUniqueEntity;
use 
DoctrineCommonCollectionsArrayCollection;

/**
 * User
 *
 * @ORM\Table(name="users")
 * @ORM\Entity(repositoryClass="inventario\userBundle\Repository\UserRepository")
 * @UniqueEntity("username")
 * @UniqueEntity("email")
 * @ORM\HasLifecycleCallbacks()
 */
class User implements UserInterfaceserializable
{
   
    
    
/**
     * @ORM\OneToMany(targetEntity="\inventario\inmueblesBundle\Entity\intervencion", mappedBy="User")
     */
    
protected $intervencion;
 
    public function 
__construct()
    {
        
$this->intervencion = new ArrayCollection();
    }
    
    
/**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    
private $id;

    
/**
     * @var string
     *
     * @ORM\Column(name="username", type="string", length=50, unique=true)
     * @Assert\NotBlank()
     */
    
private $username;

    
/**
     * @var string
     *
     * @ORM\Column(name="primer_apellido", type="string", length=100)
     * @Assert\NotBlank()
     */
    
private $primerApellido;

    
/**
     * @var string
     *
     * @ORM\Column(name="segundo_apellido", type="string", length=100)
     * @Assert\NotBlank()
     */
    
private $segundoApellido;

    
/**
     * @var string
     *
     * @ORM\Column(name="email", type="string", length=100, unique=true)
     * @Assert\NotBlank()
     * @Assert\Email()
     */
    
private $email;

    
/**
     * @var string
     *
     * @ORM\Column(name="password", type="string",  length=255)
     */
    
private $password;

    
/**
     * @var string
     *
     * @ORM\Column(name="role", type="string",columnDefinition="ENUM('ROLE_ADMIN','ROLE_USER')", length=50)
     * @Assert\NotBlank()
     * @Assert\Choice(choices = {"ROLE_ADMIN", "ROLE_USER"})
     */
    
private $role;

    
/**
     * @var bool
     *
     * @ORM\Column(name="is_active", type="boolean")
     * 
     */
    
private $isActive;

    
/**
     * @var \DateTime
     *
     * @ORM\Column(name="created_at", type="datetime")
     */
    
private $createdAt;

    
/**
     * @var \DateTime
     *
     * @ORM\Column(name="updated_at", type="datetime")
     */
    
private $updatedAt;


    
/**
     * Get id
     *
     * @return int
     */
    
public function getId()
    {
        return 
$this->id;
    }

    
/**
     * Set username
     *
     * @param string $username
     *
     * @return User
     */
    
public function setUsername($username)
    {
        
$this->username $username;

        return 
$this;
    }

    
/**
     * Get username
     *
     * @return string
     */
    
public function getUsername()
    {
        return 
$this->username;
    }

    
/**
     * Set primerApellido
     *
     * @param string $primerApellido
     *
     * @return User
     */
    
public function setPrimerApellido($primerApellido)
    {
        
$this->primerApellido $primerApellido;

        return 
$this;
    }

    
/**
     * Get primerApellido
     *
     * @return string
     */
    
public function getPrimerApellido()
    {
        return 
$this->primerApellido;
    }

    
/**
     * Set segundoApellido
     *
     * @param string $segundoApellido
     *
     * @return User
     */
    
public function setSegundoApellido($segundoApellido)
    {
        
$this->segundoApellido $segundoApellido;

        return 
$this;
    }

    
/**
     * Get segundoApellido
     *
     * @return string
     */
    
public function getSegundoApellido()
    {
        return 
$this->segundoApellido;
    }

    
/**
     * Set email
     *
     * @param string $email
     *
     * @return User
     */
    
public function setEmail($email)
    {
        
$this->email $email;

        return 
$this;
    }

    
/**
     * Get email
     *
     * @return string
     */
    
public function getEmail()
    {
        return 
$this->email;
    }

    
/**
     * Set password
     *
     * @param string $password
     *
     * @return User
     */
    
public function setPassword($password)
    {
        
$this->password $password;

        return 
$this;
    }

    
/**
     * Get password
     *
     * @return string
     */
    
public function getPassword()
    {
        return 
$this->password;
    }

    
/**
     * Set role
     *
     * @param string $role
     *
     * @return User
     */
    
public function setRole($role)
    {
        
$this->role $role;

        return 
$this;
    }

    
/**
     * Get role
     *
     * @return string
     */
    
public function getRole()
    {
        return 
$this->role;
    }

    
/**
     * Set isActive
     *
     * @param boolean $isActive
     *
     * @return User
     */
    
public function setIsActive($isActive)
    {
        
$this->isActive $isActive;

        return 
$this;
    }

    
/**
     * Get isActive
     *
     * @return bool
     */
    
public function getIsActive()
    {
        return 
$this->isActive;
    }

    
/**
     * Set createdAt
     *
     * @param \DateTime $createdAt
     *
     * @return User
     */
    
public function setCreatedAt($createdAt)
    {
        
$this->createdAt $createdAt;

        return 
$this;
    }

    
/**
     * Get createdAt
     *
     * @return \DateTime
     */
    
public function getCreatedAt()
    {
        return 
$this->createdAt;
    }

    
/**
     * Set updatedAt
     *
     * @param \DateTime $updatedAt
     *
     * @return User
     */
    
public function setUpdatedAt($updatedAt)
    {
        
$this->updatedAt $updatedAt;

        return 
$this;
    }

    
/**
     * Get updatedAt
     *
     * @return \DateTime
     */
    
public function getUpdatedAt()
    {
        return 
$this->updatedAt;
    }
     
/**
     * @ORM\PrePersist
     */
        
public function setCreatedAtValue()
    {
        
$this->createdAt = new DateTime();
    }

    
/**
     * @ORM\PrePersist
     * @ORM\PreUpdate
     */
    
public function setUpdatedAtValue()
    {
        
$this->updatedAt = new DateTime();
    }
    

    public function 
getSalt()
    {
        
// you *may* need a real salt depending on your encoder
        // see section on salt below
        
return null;
    }
    



    public function 
eraseCredentials()
    {
    }
    public function 
getRoles()
    {
         return 
$this->role;
    }

    
/** @see \Serializable::serialize() */
    
public function serialize()
    {
        return 
serialize(array(
            
$this->id,
            
$this->username,
            
$this->password,
            
// see section on salt below
            // $this->salt,
        
));
    }

    
/** @see \Serializable::unserialize() */
    
public function unserialize($serialized)
    {
        list (
            
$this->id,
            
$this->username,
            
$this->password,
            
// see section on salt below
            // $this->salt
        
) = unserialize($serialized);
    }
        public function 
__toString()
    {
        return 
$this->getUsername();
    }
    
//////////////////////SEGURIDAD AÑADIDO
    
public function isAccountNonExpired()
    {
            return 
true;
    }

    public function 
isAccountNonLocked()
    {
            return 
true;
    }

    public function 
isCredentialsNonExpired()
    {
            return 
true;
    }

    public function 
isEnabled()
    {
        return 
$this->isActive;
    }
    
    
    
    
    
}
  #3 (permalink)  
Antiguo 17/04/2016, 11:36
Avatar de hhs
hhs
Colaborador
 
Fecha de Ingreso: junio-2013
Ubicación: México
Mensajes: 2.995
Antigüedad: 10 años, 9 meses
Puntos: 379
Respuesta: Seguridad: Creando un login con tabla User

Que versión de Symfony estas usando ?
__________________
Saludos
About me
Laraveles
A class should have only one reason to change.
  #4 (permalink)  
Antiguo 17/04/2016, 13:07
 
Fecha de Ingreso: enero-2016
Mensajes: 15
Antigüedad: 8 años, 2 meses
Puntos: 0
Respuesta: Seguridad: Creando un login con tabla User

Hola.
Posiblemente otra mala elección la 3.
Gracias.
Saludos Luis.
  #5 (permalink)  
Antiguo 18/04/2016, 08:32
Avatar de hhs
hhs
Colaborador
 
Fecha de Ingreso: junio-2013
Ubicación: México
Mensajes: 2.995
Antigüedad: 10 años, 9 meses
Puntos: 379
Respuesta: Seguridad: Creando un login con tabla User

Si estas usando la versión 3 sigue la documentación de esa versión: http://symfony.com/doc/current/cookb...gin_setup.html
tienes algunos errores en tu documento security.yml. como dos providers y firewalls repetidos, solo puede haber una clave de cada uno. por favor revisar la documentación: http://symfony.com/doc/current/refer.../security.html
__________________
Saludos
About me
Laraveles
A class should have only one reason to change.
  #6 (permalink)  
Antiguo 19/04/2016, 13:20
 
Fecha de Ingreso: enero-2016
Mensajes: 15
Antigüedad: 8 años, 2 meses
Puntos: 0
Respuesta: Seguridad: Creando un login con tabla User

Hola.
Con este security.yml, cuando no es un usuario me indica "Credenciales no validas":
Código PHP:
# To get started with security, check out the documentation:
# http://symfony.com/doc/current/book/security.html

security:

    
firewalls:

        
main:
            
anonymous: ~
            
form_login:
                    
login_path: /login
                    check_path
: /login
    
    
# disables authentication for assets and the profiler, adapt it according to your needs
    # dev:
    #        pattern: ^/(_(profiler|wdt)|css|images|js)/
    #        security: false
    #    login:
    #        pattern:  ^/login$
    #        security: false    
            
    #    secured_area:
    #        pattern:    ^/
    #        anonymous:  ~
    #        provider: our_db_provider 
    #        form_login:
    #            login_path:  /login
    #            check_path:  /login
    #        logout:
    #            path: user_logout
    #            target: /


    
access_control:
        - { 
path: ^/loginrolesIS_AUTHENTICATED_ANONYMOUSLY }
        - { 
path: ^/, rolesROLE_ADMIN }     

    
providers:
        
our_db_provider:
            
entity:
                class: 
userBundle:User
                property
username
                
# if you're using multiple entity managers
                # manager_name: customer

       
        
    
encoders:
        
inventariouserBundleEntityUser:
            
algorithmbcrypt
            cost
12 
Parece que por ahora funciona.
Ahora, cuando el usuario y contraseña son correctos y del tipo ROLE_ADMIN me daba un error :
Código PHP:
Catchable Fatal ErrorArgument 4 passed to SymfonyComponentSecurityCoreAuthenticationTokenUsernamePasswordToken::__construct() must be of the type array, string givencalled in /home/ubuntu/workspace/vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Provider/UserAuthenticationProvider.php on line 96 and defined 
Código PHP:
     *
     * @
throws InvalidArgumentException
     
*/
    public function 
__construct($user$credentials$providerKey, array $roles = array())
    {
        
parent::__construct($roles); 
He visto que si pongo
Código PHP:
    public function getRoles()
    {
         return array(
'ROLE_ADMIN'); 
    } 
Como recomiendan en algunas paginas, se autentifica pero creo que todos los usuarios son ADMIN.
Si pongo, como es lo mas normal:
Código PHP:
    public function getRoles()
    {
      return 
$this->role;
      
    } 
Me da el mismo error.
Esta claro que hay que devolver un array como indica el error, pero ¿Como le mando el tipo de usuario que contiene el atributo role en formato array?

Otra cosa, con el DefaultController del ejemplo, que me indica "hhs", ya no me da el error
"undefined method named "getRequest" ",¿ pero ahora como lo redirijo a una pagina si es ADMIN y otra si es USER?

Saludos y gracias, Luis.
  #7 (permalink)  
Antiguo 19/04/2016, 14:22
 
Fecha de Ingreso: enero-2016
Mensajes: 15
Antigüedad: 8 años, 2 meses
Puntos: 0
Respuesta: Seguridad: Creando un login con tabla User

Hola.
Empieza a cumplirse "El principio de Peter".
Sobre lo que debe devolver getRoles()

Código PHP:
    public function getRoles()
    {
         
//return $this->role;
         
if($this->role=='ROLE_ADMIN')
         return array(
'ROLE_ADMIN'); 
         else return array(
'ROLE_USER'); 
    } 
Ahora el problema lo tengo con los User que deben entrar en" /inventario", quedando el fichero SECURITY.YML
Código PHP:
    access_control:
        - { 
path: ^/loginrolesIS_AUTHENTICATED_ANONYMOUSLY }
        - { 
path: ^/, rolesROLE_ADMIN }    
        - { 
path: ^/inventariorolesROLE_USER 
Pero al "loguear" me indica "Access Denied.", creo que es debido a que no lo mando a ningún sitio y entrara en una parte del administrador
Saludos gracias.
  #8 (permalink)  
Antiguo 19/04/2016, 14:45
Avatar de hhs
hhs
Colaborador
 
Fecha de Ingreso: junio-2013
Ubicación: México
Mensajes: 2.995
Antigüedad: 10 años, 9 meses
Puntos: 379
Respuesta: Seguridad: Creando un login con tabla User

Para el asunto de los roles:
Código PHP:
Ver original
  1. public function getRoles()
  2.     {
  3.        return $this->roles->toArray();
  4.     }

Para redireccionar tienes que usar un handler; en este caso tienes que hacer una implementación del la interfaz AuthenticationSuccessHandlerInterface
https://github.com/symfony/symfony/b...rInterface.php
En este hilo se trato un poco el tema: http://www.forosdelweb.com/f181/aute...fony2-1145646/
__________________
Saludos
About me
Laraveles
A class should have only one reason to change.
  #9 (permalink)  
Antiguo 20/04/2016, 13:38
 
Fecha de Ingreso: enero-2016
Mensajes: 15
Antigüedad: 8 años, 2 meses
Puntos: 0
Respuesta: Seguridad: Creando un login con tabla User

Hola.
Con respecto al getRoles me da el error
Código PHP:
ErrorCall to a member function toArray() on a non-object 
He dejado este, que funciona bien.
Código PHP:
    public function getRoles() 
    { 
         if(
$this->role=='ROLE_ADMIN'
         return array(
'ROLE_ADMIN');  
         else return array(
'ROLE_USER');  
    } 
Con respecto a la redirección he seguido su consejo, pero desde esta página
[URL="http://www.solucionex.com/blog/symfony2-operaciones-despues-de-hacer-login"]http://www.solucionex.com/blog/symfony2-operaciones-despues-de-hacer-login[/URL]

el único cambio que he efectuado es:
Código PHP:
services:
  
redirect.after.login:
    class: 
AppBundleRedirectionLoginRedirection
    arguments
: [@router
me indicaba una mal formación del fichero y lo puse
Código PHP:
services:
    
redirect.after.login:
        class: 
AppBundleRedirectionLoginRedirection
        arguments
:
            
router"@router" 
De esta forma ya no me indicaba que la estructura del fichero YAML no era correcta.
Bueno Muchísimas gracias, voy ha seguir con el proyecto depurando algunos errores que ya había comentado en otros mensajes.
Saludos Luis.

Etiquetas: creando, login, seguridad, tabla
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 11:26.