Mécanisme d'authentification basé sur la doctrine dans le projet Symfony2
Je suis en train de travailler sur un petit Doctrine2 projet soutenu par l'aide de Symfony2 pour la première fois. Actuellement je suis aux prises avec le composant de sécurité de symfony2, pour être exact, avec le mécanisme d'authentification décrites dans le la documentation.
Je veux utiliser un formulaire d'authentification, et a tout fait indiqué dans les docs:
J'ai une sécurité.yml fichier de configuration qui ressemble à ceci:
security.config:
firewalls:
admin:
pattern: /admin/.*
form-login: true
logout: true
login_path: /login
check_path: /validateLogin
always_use_default_target_path: false
target_path_parameter: target
check_page:
pattern: /validateLogin
form-login: true
login_path: /login
check_path: /validateLogin
always_use_default_target_path: false
target_path_parameter: target
public:
pattern: /.*
security: false
providers:
admin:
password_encoder: md5
entity:
class: AdminBundle:User
property: username
access_control:
- { path: /admin/.*, role: ROLE_ADMIN }
- { path: /validateLogin, role: IS_AUTHENTICATED_ANONYMOUSLY }
role_hierarchy:
ROLE_ADMIN: ROLE_USER
La check_page est exclu de la "secureless" zone après la lecture d'un fil similaire sur devcomments.
Dans ma configuration de routage-je inclure deux règles pour l'authentification:
_security_login:
pattern: /login
defaults:
_controller: PublicBundle:Auth:index
_security_check:
pattern: /validateLogin
La classe d'entité, je suis à l'aide de représenter un utilisateur est un Doctrine2 entité et met en œuvre la AccountInterface:
<?php
namespace Application\AdminBundle\Entity;
use Symfony\Component\Security\User\AccountInterface;
/**
* @orm:Entity
*/
class User implements AccountInterface
{
/**
* @orm:Id
* @orm:Column(type="integer")
* @orm:GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* @orm:Column(type="string", length="255")
*/
protected $username;
/**
* @orm:Column(type="string", length="40")
*/
protected $password;
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = $id;
}
public function getUsername()
{
return $this->username;
}
public function setUsername($username)
{
$this->username = $username;
}
public function getPassword()
{
return $this->password;
}
public function setPassword($password)
{
$this->password = $password;
}
/**
* Implementing the AccountInterface interface
*/
public function __toString()
{
return $this->getUsername();
}
public function getRoles()
{
return array('ROLE_ADMIN');
}
public function eraseCredentials()
{
}
public function getSalt()
{
return $this->getId();
}
}
Dans la classe de l'action authcontroller je suis en utilisant le code d'exemple de la symfony2 documents:
public function indexAction()
{
if ($this->get('request')->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
$error = $this->get('request')->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
} else {
$error = $this->get('request')->getSession()->get(SecurityContext::AUTHENTICATION_ERROR);
}
return
$this->render(
'PublicBundle:Auth:index.twig',
array(
'last_username' => $this->get('request')->getSession()->get(SecurityContext::LAST_USERNAME),
'error' => $error));
}
Maintenant vient le problème: La règle de redirection à partir de http://symfony2.localhost/app_dev.php/admin/test à http://symfony2.localhost/app_dev.php/login fonctionne, mais après avoir entré le nom d'utilisateur/mot de passe et en soumettant le formulaire de connexion, je suis redirigé vers l'url de connexion à nouveau sans un message d'erreur.
Je sais que c'est vraiment une question fondamentale, mais depuis il n'y a pas encore beaucoup de documentation sur symfony2, je pense que c'est un bon endroit pour poser ce genre de questions.
En général, il y a certains points à l'intérieur d'un projet symfony2 qui semble fonctionner comme par magie (bien sûr, DI-soutenu) qui rendent le processus d'apprentissage un peu dur. Mes pensées sur la façon dont l'authentification fonctionne est qu'il y a de magique Contrôleur qui attrape le validateLogin action, cherche une entité référentiel pour mon entité User, appels findOneBy('username' => $pseudo) et compare les mots de passe... est-ce vrai?
Je vous remercie à l'avance pour tout conseil, j'ai été googler cette question pour plus de quelques heures maintenant... 🙂
Paul
source d'informationauteur Paul
Vous devez vous connecter pour publier un commentaire.
Vous avez tort. L'authentification n'est pas n'importe quel contrôleur, c'est pourquoi vous ne précisez pas dans
_security_check
route. Auth est basé surEventDispatcher
. Chaque fois que vous pouvez spécifier certains écouteur dans votre pare-feu (par exemple.form_login
anonymous
logout
etc.) vous avez fait enregistrer un nouveau port d'écoute pourcore.security
événement.Symfony\Component\HttpKernel\Security\Firewall::handle()
est un lieu où ces auditeurs sont inscrits.Le général, flux simplifié:
_username
et_password
champs).core.security
événement est déclenché.UsernamePasswordFormAuthenticationListener
est déclenché (handle()
méthode) et vérifie si:check_path
option._username
et_password
paramètres.attemptAuthentication()
méthode).DaoAuthenticationProvider
est tiré et il essaie de récupérer de l'utilisateur à l'aide de la Doctrine de l'utilisateur du référentiel de la classe.UsernamePasswordToken
(qui contiennent$user
objet renvoyé parloadUserByUsername()
méthode) est retourné, et l'utilisateur est redirigé.En effet, le mécanisme de sécurité est assez complexe et difficile à comprendre (la documentation n'est pas encore terminé). Mais lorsque vous avez enfin de comprendre comment il fonctionne, alors vous verrez comment puissant mécanisme de il est.
J'ai écrit mon propre mécanisme d'authentification et il fonctionne très bien.
Configuration:
Je suis en utilisant un fournisseur personnalisé et le codeur.
Comme vous pouvez le voir
/panel/*
est limité, alors que/*
est public.Service
security.encoder.sha512
est équipé d'un encodeur:Project\SiteBundle\Entity\User
:Project\SiteBundle\Repository\UserRepository
De la sécurité des routes et le contrôleur est le même que le vôtre.
Vous devez utiliser le https://github.com/FriendsOfSymfony/FOSUserBundle FOS UserBundle, elle met en œuvre tout cela avec Doctrine 2 et a des tonnes de fonctionnalités.
La raison, essentiellement, pourquoi la page de connexion de charge à nouveau avec aucun message d'erreur n'est parce que, ironiquement, vos paramètres de sécurité ne sont pas mis en place pour permettre l'accès anonyme à la page de connexion.