Académique Documents
Professionnel Documents
Culture Documents
Achref El Mouelhi
elmouelhi.achref@gmail.com
1 Introduction
2 Création d’utilisateur
3 Préparation de l’authentification
4 Déconnexion
5 Contrôle d’accès
Dans security.yaml
Dans le contrôleur
Dans la vue
6 Utilisateur authentifié
Dans le contrôleur
Dans la vue
7 Rôles hiérarchiques
Symfony
But de la sécurité
H I ©
Interdire, à un utilisateur, l’accès à une ressource à laquelle il n’a pas
droit
UEL
O
f E LM
ch r e
©A
Symfony
But de la sécurité
H I ©
Interdire, à un utilisateur, l’accès à une ressource à laquelle il n’a pas
droit
UEL
O
f E LM
Deux étapes
ch r e
©A
Qui veut accéder à la ressource ?
A t-il le droit d’y accéder ?
Symfony
Configuration de la sécurité
Symfony
Configuration de la sécurité
Symfony
Configuration de la sécurité
En utilisant les annotations
H I ©
Et en définissant quelques règles dans UEL
O
config/packages/security.yaml
f E LM
ch r e
Mais on peut aussi utiliser :
©A
le format XML
les tableaux imbriqués de PHP
Symfony
Contenu de security.yaml
security:
# https://symfony.com/doc/current/security.html#where-do-users-come
-from-user-providers
H I ©
EL
providers:
users_in_memory: { memory: null }
firewalls:
O U
dev:
f E LM
pattern: ˆ/(_(profiler|wdt)|css|images|js)/
security: false
ch r e
©A
main:
anonymous: lazy
provider: users_in_memory
access_control:
# - { path: ˆ/admin, roles: ROLE_ADMIN }
# - { path: ˆ/profile, roles: ROLE_USER }
Symfony
Plusieurs étapes
H I ©
se L
Préparation de la partie utilisateur (qui va E connecter)
U
L MO (formulaire
Préparation de la partie authentification
e f E
d’authentification, déconnexion...)
r
Gestion de rA ch
© ôles
Symfony
H I ©
Si on ne choisit pas la version complète à la crE
U L du projet
éation
L MO
composer require symfony/security-bundle
r e f E
A ch
©
Symfony
Pour créer la classe User
I ©
répondez à Do you want to store user data in the database (via
H
EL
Doctrine)? par yes
O U
répondez à Enter a property name that will be the unique "display"
name for the user par email
f E LM
r e
répondez à Does this app need to hash/check user passwords? par yes
ch
©A
Symfony
Pour créer la classe User
I ©
répondez à Do you want to store user data in the database (via
H
EL
Doctrine)? par yes
O U
répondez à Enter a property name that will be the unique "display"
name for the user par email
f E LM
r e
répondez à Does this app need to hash/check user passwords? par yes
ch
©A
Le résultat est
created: src/Entity/User.php
created: src/Repository/UserRepository.php
updated: src/Entity/User.php
updated: config/packages/security.yaml
security:
encoders:
App\Entity\User:
algorithm: auto
# https://symfony.com/doc/current/security.html#where-do-users-come
-from-user-providers
providers:
H I ©
EL
# used to reload user from session & other features (e.g.
switch_user)
O U
LM
app_user_provider:
entity:
e f E
class: App\Entity\User
r
ch
property: email
©A
firewalls:
dev:
pattern: ˆ/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: lazy
provider: app_user_provider
access_control:
Symfony
I ©
et ensuite la commande php bin/console doctrine:migrations:migrate
H
UEL
O
f E LM
ch r e
©A
Symfony
I ©
et ensuite la commande php bin/console doctrine:migrations:migrate
H
UEL
O
f E LM
r e
Pour remplir la table User avec des données aléatoires
ch
©A
installez le bundle de fixture composer require --dev
doctrine/doctrine-fixtures-bundle
Symfony
Contenu généré pour UserFixtures
namespace App\DataFixtures;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
H I ©
class UserFixtures extends Fixture
UEL
O
LM
{
r e f E
public function load(ObjectManager $manager)
ch
©A
{
// $product = new Product();
// $manager->persist($product);
$manager->flush();
}
}
©
{
$user = new User();
H I
EL
$user->setEmail(’wick@wick.us’);
$user->setRoles([’ROLE_ADMIN’]);
$user,
O U
$user->setPassword($this->passwordEncoder->encodePassword(
LM
’wick’
));
$manager->persist($user);
r e f E
ch
$user2 = new User();
$user2->setEmail(’john@john.us’);
©A
$user2->setPassword($this->passwordEncoder->encodePassword(
$user2,
’john’
));
$manager->persist($user2);
$manager->flush();
}
}
©
{
$user = new User();
H I
EL
$user->setEmail(’wick@wick.us’);
$user->setRoles([’ROLE_ADMIN’]);
$user,
O U
$user->setPassword($this->passwordEncoder->encodePassword(
LM
’wick’
));
$manager->persist($user);
r e f E
ch
$user2 = new User();
$user2->setEmail(’john@john.us’);
©A
$user2->setPassword($this->passwordEncoder->encodePassword(
$user2,
’john’
));
$manager->persist($user2);
$manager->flush();
}
}
use App\Entity\User;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
Symfony
H I ©
EL
Pour insérer l’utilisateur dans la base de données, exécutez
U
O
LM
php bin/console doctrine:fixtures:load ou php
bin/console d:f:l
r e f E
ch
©A
> SecurityController
ch r e
©A
Do you want to generate a ’/logout’ URL? (yes/no) [yes]:
> yes
> SecurityController
ch r e
©A
Do you want to generate a ’/logout’ URL? (yes/no) [yes]:
> yes
Le résultat est
created: src/Security/LoginFormAuthenticator.php
updated: config/packages/security.yaml
created: src/Controller/SecurityController.php
created: templates/security/login.html.twig
H & H: Research and Training 15 / 34
Préparation de l’authentification
Symfony
c h re
©A
Symfony
c h re
©A
Remarque
Symfony
Pour résoudre ce problème, il faut modifier la méthode
onAuthenticationSuccess définie dans
security/LoginFormAuthenticator pour rediriger vers la
route home route
public function onAuthenticationSuccess(Request
H I ©
$request, TokenInterface $token, $providerKey)
UEL
O
LM
{
f E
if ($targetPath = $this->getTargetPath($request
r e
ch
->getSession(), $providerKey)) {
} ©A
return new RedirectResponse($targetPath);
Symfony
Pour modifier les messages d’erreurs de la page d’accueil, créez un fichier
security.en.xlf dans translations avec le contenu suivant
<?xml version="1.0"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1
.2">
<file source-language="en" datatype="plaintext" original="
H I ©
EL
file.ext">
<body>
O U
LM
<trans-unit id="Invalid credentials.">
r e E
<source>Invalid credentials.</source>
f
<target>Le mot de passe est invalide</target>
ch
©A
</trans-unit>
<trans-unit id="Email could not be found.">
<source>Email could not be found.</source>
<target>Email non-trouvé</target>
</trans-unit>
</body>
</file>
</xliff>
Symfony
Pour se déconnecter
essayez la route /logout H I ©
UEL
O
f E LM
ch r e
©A
Symfony
Pour se déconnecter
essayez la route /logout H I ©
UEL
O
f E LM
Question ch r e
©A
Comment rediriger vers la page d’authentification ?
Symfony
Symfony
Symfony
Symfony
access_control:
- { path: ’ˆ/login’, roles: IS_AUTHENTICATED_ANONYMOUSLY }
H I ©
- { path: ’ˆ/*’, roles: [IS_AUTHENTICATED_FULLY] }
U EL
O
f E LM
ch r e
©A
Symfony
access_control:
- { path: ’ˆ/login’, roles: IS_AUTHENTICATED_ANONYMOUSLY }
H I ©
- { path: ’ˆ/*’, roles: [IS_AUTHENTICATED_FULLY] }
U EL
O
f E LM
r e
Pour autoriser les utilisateurs qui ont le rôle admin (ROLE ADMIN)
ch
access_control:
©A
- { path: ’ˆ/login’, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ’ˆ/*’, roles: [ROLE_ADMIN] }
Symfony
Remarques
f E LM
Les mots composants le nom d’un rôle doivent être séparés par
un underscore. ch r e
©A
La clé roles accepte une valeur ou un tableau de valeurs
Symfony
access_control:
H I ©
EL
- { path: ’ˆ/personne’, roles: [ROLE_USER, ROLE_ADMIN] }
O U
f E LM
ch r e
©A
Symfony
access_control:
H I ©
EL
- { path: ’ˆ/personne’, roles: [ROLE_USER, ROLE_ADMIN] }
O U
f E LM
ch r e
En testant, le message d’erreur suivant est affiché
©A
Passing more than one Security attribute to "Symfony\Component
\Security\Core\Authorization\AccessDecisionManager::decide()"
is not supported.
Symfony
Explication
Symfony
Remplacez
public function decide(TokenInterface $token, array $attributes,
$object = null): bool
H I ©
U EL
O
f E LM
ch r e
©A
Symfony
Remplacez
public function decide(TokenInterface $token, array $attributes,
$object = null): bool
Par
H I ©
public function decide(TokenInterface $token, array $attributes,
U EL
O
$object = null/*, bool $allowMultipleAttributes = false*/): bool
f E LM
ch r e
©A
Symfony
Remplacez
public function decide(TokenInterface $token, array $attributes,
$object = null): bool
Par
H I ©
public function decide(TokenInterface $token, array $attributes,
U EL
O
$object = null/*, bool $allowMultipleAttributes = false*/): bool
f E LM
ch r e
©A
Et
$result = $this->manager->decide($token, $attributes, $object);
Symfony
Remplacez
public function decide(TokenInterface $token, array $attributes,
$object = null): bool
Par
H I ©
public function decide(TokenInterface $token, array $attributes,
U EL
O
$object = null/*, bool $allowMultipleAttributes = false*/): bool
f E LM
ch r e
©A
Et
$result = $this->manager->decide($token, $attributes, $object);
Par
$result = $this->manager->decide($token, $attributes, $object, 3 < \
func_num_args() && func_get_arg(3));
Symfony
Symfony
Symfony
Symfony
Symfony
Pour récupérer l’utilisateur authentifié dans une méthode de
contrôleur
class PersonneController extends AbstractController
{
/**
H I ©
* @Route("/personne/add", name="personne_add")
U EL
O
LM
*/
f E
public function addForm(EntityManagerInterface
r e
ch
$entityManager, Request $request)
{
©A
$this->denyAccessUnlessGranted(’
IS_AUTHENTICATED_FULLY’);
$user = $this->getUser();
// le reste du contenu
}
Symfony
Pour récupérer les rôles de l’utilisateur
class PersonneController extends AbstractController
{
/**
* @Route("/personne/add", name="personne_add")
H I ©
*/
U EL
O
LM
public function addForm(EntityManagerInterface
f E
$entityManager, Request $request)
r e
{
ch
©A
$this->denyAccessUnlessGranted(’
IS_AUTHENTICATED_FULLY’);
$user = $this->getUser();
roles = $user->getRoles();
// le reste du contenu
}
Symfony
f
<p>Email: {{ app.user.email }}</p>
r e E
{% endif %}
ch
©A
Symfony
Dans security.yaml
security:
# ...
role_hierarchy:
H I ©
ROLE_ADMIN: ROLE_USER
UEL
O
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
f E LM
ch r e
Remarques
©A
L’utilisateur ayant le rôle ROLE ADMIN a aussi le rôle ROLE USER
L’utilisateur ayant le rôle ROLE SUPER ADMIN a aussi les rôle ROLE ADMIN,
ROLE USER et ROLE ALLOWED TO SWITCH