Bonjour,
Je découvre actuellement le framework symfony. J’essaie de coder des comptes utilisateurs qui pourront avoir deux roles : ROLE_ADMIN ou ROLE_USER mais lorsque j’essaye de me connecter, j’obtiens le message « Authentication request could not be processed due to a system problem. » Je sollicite votre aide après des jours passés à m’arracher les cheveux (j’ai bien évidemment fait des recherches dans les différentes documentations ainsi que sur les forums sans succès). Je suis encore débutant en programmation web et j’aimerais vraiment trouver une solution à ce problème.
Voici le contenu de mon security.yaml :
security:
encoders:
App\Entity\Utilisateur:
algorithm: argon2i
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: App\Entity\User
property: username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
form_login:
login_path: login
check_path: login
logout:
path: app_logout
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#firewalls-authentication
# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/, roles: ROLE_USER }
De mon UtilisateurFixtures, qui me permet de créer des utilisateurs factices :
<?php
namespace App\DataFixtures;
use App\Entity\Utilisateur;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\User\User;
//use Symfony\Bridge\Doctrine\Tests\Fixtures\User;
class UtilisateurFixtures extends Fixture
{
/**
* @var UserPasswordEncoderInterface
*/
private $encoder;
public function __construct(UserPasswordEncoderInterface $encoder)
{
$this->encoder = $encoder;
}
public function load(ObjectManager $manager)
{
$user = new Utilisateur();
$user->setUsername('demo3');
$user->setPassword($this->encoder->encodePassword($user,'demo3'));
$user->setRoles(['ROLE_USER', 'ROLE_ADMIN']);
$manager->persist($user);
$manager->flush();
}
}
De mon SecurityController :
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class SecurityController extends AbstractController
{
/**
* @Route("/login", name="login")
*/
public function login(AuthenticationUtils $authenticationUtils): Response
{
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
}
/**
* @Route("/logout", name="app_logout", methods={"GET"})
*/
public function logout()
{
// controller can be blank: it will never be executed!
throw new \Exception('Don\'t forget to activate logout in security.yaml');
}
}
De mon Utilisateur.php :
<?php
namespace App\DataFixtures;
use App\Entity\Utilisateur;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\User\User;
//use Symfony\Bridge\Doctrine\Tests\Fixtures\User;
class UtilisateurFixtures extends Fixture
{
/**
* @var UserPasswordEncoderInterface
*/
private $encoder;
public function __construct(UserPasswordEncoderInterface $encoder)
{
$this->encoder = $encoder;
}
public function load(ObjectManager $manager)
{
$user = new Utilisateur();
$user->setUsername('demo3');
$user->setPassword($this->encoder->encodePassword($user,'demo3'));
$user->setRoles(['ROLE_USER', 'ROLE_ADMIN']);
$manager->persist($user);
$manager->flush();
}
}
De ma vue qui affiche mon formulaire de connexion :
{% extends 'base.html.twig' %}
{% block title %}Log in!{% endblock %}
{% block body %}{% if error %}
<div>{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
<form action="{{ path('login') }}" method="post">
<label for="username">Username:</label>
<input type="text" id="username" name="_username" value="{{ last_username }}" />
<label for="password">Password:</label>
<input type="password" id="password" name="_password" />
<input type="hidden" name="_target_path" value="/" />
{#
If you want to control the URL the user
is redirected to on success (more details below)
<input type="hidden" name="_target_path" value="/account" />
#}
<button type="submit">login</button>
</form>
{% endblock %}
De mon UtilisateurRepository :
<?php
namespace App\Repository;
use App\Entity\Utilisateur;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface;
use Symfony\Bridge\Doctrine\RegistryInterface;
/**
* @method Utilisateur|null find($id, $lockMode = null, $lockVersion = null)
* @method Utilisateur|null findOneBy(array $criteria, array $orderBy = null)
* @method Utilisateur[] findAll()
* @method Utilisateur[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class UtilisateurRepository extends ServiceEntityRepository
{
public function __construct(RegistryInterface $registry)
{
parent::__construct($registry, Utilisateur::class);
}
// /**
// * @return Utilisateur[] Returns an array of Utilisateur objects
// */
/*
public function findByExampleField($value)
{
return $this->createQueryBuilder('u')
->andWhere('u.exampleField = :val')
->setParameter('val', $value)
->orderBy('u.id', 'ASC')
->setMaxResults(10)
->getQuery()
->getResult()
;
}
*/
/*
public function findOneBySomeField($value): ?Utilisateur
{
return $this->createQueryBuilder('u')
->andWhere('u.exampleField = :val')
->setParameter('val', $value)
->getQuery()
->getOneOrNullResult()
;
}
*/
}
J’arrive bien à remplir ma base de donnée avec des fausses données. Ma base de donnée a trois champs dans la table « Utilisateur » : username, password et roles. Je pense que j'ai mal configuré quelque chose au niveau du security mais je ne sais pas où. N’hésitez pas à me dire si vous avez besoin de quoi que ce soit d’autres.
Merci d’avoir pris le temps de lire ce message.