Les points d’entrée ne reçoivent pas de demandeur en argument. Ils le demandent à un service, et remplacer ce service est ce qui fait fonctionner tout le composant dans une application sans Symfony Security.
interface RequesterProviderInterface
{
public function getRequester(): mixed;
}
Une méthode, aucun argument, aucun framework dans la signature. L’attribut de contrôleur, les règles d’URL, les fonctions Twig et les gardes de console passent tous par elle.
Les deux fournisseurs fournis
- Le fournisseur statique rend toujours le même demandeur, en général un compte de service dans un contexte de console. C’est le défaut.
- Le fournisseur de stockage de jeton rend le jeton actuellement dans le stockage de jetons de Symfony. Il est câblé pour vous quand Security est installé.
Une application qui installe le bundle aux côtés de SecurityBundle n’a donc rien à faire : le jeton courant est le demandeur, et tous les points d’entrée voient ce que voit Security.
Le pointer sur le vôtre
access_control.requester_provider est un alias. Remplacez-le, et toute l’application suit :
services:
App\Security\CurrentRequesterProvider: ~
access_control.requester_provider:
alias: App\Security\CurrentRequesterProvider
Ce qu’il y a dedans vous regarde : une session, un JWT décodé dans un écouteur, une clé d’API résolue depuis un en-tête, un objet locataire, une simple chaîne. N’importe quoi peut être un demandeur, donc n’importe quoi peut sortir de cette méthode.
Sur une console, l’identité se déclare
Il n’y a pas de jeton dans une console, et pas de session où en lire un. Le fournisseur statique est la réponse honnête : l’identité est un compte de service que l’application nomme, et les mêmes gardes s’appliquent alors à une commande comme à un contrôleur.
services:
AccessControl\Requester\StaticRequesterProvider:
arguments:
$requester: '@App\Security\ServiceAccount'
access_control.requester_provider:
alias: AccessControl\Requester\StaticRequesterProvider
L’application de démonstration va un pas plus loin et prend une option --as, de sorte qu’une commande peut tourner sous une identité choisie et que le refus se lit dans le terminal. C’est un modèle honnête pour une console de maintenance : l’identité est écrite dans l’invocation plutôt que supposée.
Lier un demandeur à une question
RequesterBoundChecker est le service qui réunit le demandeur courant et une question, et c’est par lui que passent is_granted() et les aides de contrôleur.
$checker->isGranted('EDIT', $post); // bool
$checker->decide('EDIT', $post); // the full AccessDecision
Pour interroger au sujet de quelqu’un qui n’est pas le demandeur courant, n’allez pas chercher un moyen d’échanger le fournisseur le temps d’un appel. Construisez la requête vous-même et remettez-la au gestionnaire, ce qui se lit d’ailleurs plus simplement :
$accessControlManager->decide(new AccessRequest($otherUser, 'EDIT', $post));
Un écran d’administration qui liste ce que chaque compte pourrait faire est exactement cet appel dans une boucle, et la page des demandeurs donne le reste.