Scroll
Beperk toegang tot Taxonomy-termenvocabularium met behulp van een Event Subscriber
Soms heb je vaste, permanente categorieën nodig op de site die niet per ongeluk gewijzigd mogen worden. In dit geval kun je gebruikmaken van aangepaste code met een Event Subscriber.
Laten we een nieuwe Event Subscriber-klasse toevoegen in een aangepaste module.
drupalbook_custom.services.yml
services:
drupalbook_custom.tag_redirect_subscriber:
class: Drupal\drupalbook_custom\EventSubscriber\TagRedirectSubscriber
arguments:
- '@entity_type.manager'
- '@current_user'
tags:
- { name: event_subscriber }
En voeg onze Event Subscriber toe in drupalbook_custom/src/EventSubscriber/TagRedirectSubscriber:
<?php
namespace Drupal\drupalbook_custom\EventSubscriber;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Drupal\Core\Session\AccountProxyInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* Verwijst niet-beheerders door vanaf de adminpagina’s van de tag-vocabulaire.
*
* Een subscriber op request-niveau wordt vroeg uitgevoerd, waardoor we het
* verzoek kunnen onderbreken en een redirectresponse kunnen retourneren voordat
* de bijbehorende controller wordt uitgevoerd.
*/
class TagRedirectSubscriber implements EventSubscriberInterface {
/**
* De entity type manager service.
*
* Wordt als voorbeelddependency behouden; niet strikt nodig voor de huidige
* logica, maar handig voor toekomstige uitbreidingen.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected EntityTypeManagerInterface $entityTypeManager;
/**
* De huidige gebruiker (proxy service).
*
* Wordt gebruikt om snel gebruikersrollen te controleren om beheerders
* toegang te geven.
*
* @var \Drupal\Core\Session\AccountProxyInterface
*/
protected AccountProxyInterface $currentUser;
/**
* Constructor voor de subscriber.
*/
public function __construct(
EntityTypeManagerInterface $entity_type_manager,
AccountProxyInterface $current_user,
) {
$this->entityTypeManager = $entity_type_manager;
$this->currentUser = $current_user;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents(): array {
// Prioriteit 32 zorgt ervoor dat routering is voltooid,
// maar de controller nog niet is uitgevoerd.
return [
KernelEvents::REQUEST => ['onKernelRequest', 32],
];
}
/**
* Voert de redirect uit voor niet-beheerders die tag-adminroutes bezoeken.
*/
public function onKernelRequest(RequestEvent $event): void {
if (!$event->isMainRequest()) {
return;
}
if ($this->currentUser->hasRole('administrator')) {
return;
}
$request = $event->getRequest();
$route_name = $request->attributes->get('_route');
$redirect_to = 'https://drupalbook.org/admin/structure'
. '/taxonomy/manage/tag/overview';
switch ($route_name) {
case 'entity.taxonomy_vocabulary.overview_form':
case 'entity.taxonomy_vocabulary.overview_terms':
case 'entity.taxonomy_term.add_form':
$vocabulary = $request->attributes->get('taxonomy_vocabulary');
if (!empty($vocabulary) && $vocabulary->id() === 'tag') {
$event->setResponse(new TrustedRedirectResponse($redirect_to));
}
return;
case 'entity.taxonomy_term.edit_form':
case 'entity.taxonomy_term.delete_form':
/** @var \Drupal\taxonomy\Entity\Term|null $term */
$term = $request->attributes->get('taxonomy_term');
if ($term && $term->bundle() === 'tag') {
$event->setResponse(new TrustedRedirectResponse($redirect_to));
}
return;
default:
return;
}
}
}
De klasse TagRedirectSubscriber
is een aangepaste Event Subscriber in Drupal, bedoeld om toegang tot de beheerpagina's van een specifieke taxonomy-vocabulaire (in dit geval "tag") te beperken voor niet-beheerders. Hieronder een overzicht van de structuur en belangrijke kenmerken van de code:
1. Doel en gebruikssituatie
- Doel: Voorkom ongewenste of per ongeluk aangebrachte wijzigingen aan de "tag"-vocabulaire door niet-beheerders door te verwijzen van adminroutes.
- Voordeel: Biedt een extra laag UI-/UX-gebaseerde toegangscontrole voor kritieke taxonomieën, en waarborgt stabiliteit voor vaste categorieën.
2. Klassenstructuur en dependencies
- De klasse implementeert
EventSubscriberInterface
, en maakt zo gebruik van het event-systeem van Symfony dat Drupal hanteert. - Injectie van dependencies via de constructor:
EntityTypeManagerInterface
: Voor toekomstige uitbreidingen zoals het laden van entiteiten.AccountProxyInterface
: Voor het efficiënt controleren van gebruikersrollen.
3. Subscribed events
- De subscriber luistert naar
KernelEvents::REQUEST
met prioriteit 32.- Routering is reeds uitgevoerd (routeparameters zijn beschikbaar).
- De controller is nog niet gestart, waardoor de subscriber kan ingrijpen.
4. Redirectlogica
- De methode
onKernelRequest()
voert de toegangscontrole en redirect uit:- Alleen hoofdverzoeken: Vermijdt dubbele verwerking bij subverzoeken.
- Beheerders worden doorgelaten: Gebruikers met de rol
administrator
worden niet omgeleid. - Routecontrole: Alleen specifieke routes met betrekking tot de vocabulaire of termen worden gecontroleerd.
- Redirect van niet-beheerders:
- Bijv.
entity.taxonomy_vocabulary.overview_form
,entity.taxonomy_term.add_form
worden gecontroleerd op vocabulairetag
. - Voor
edit
endelete
-routes wordt het vocabulaire gecontroleerd via$term->bundle()
.
- Bijv.
- Vertrouwde redirect: Gebruikers worden veilig doorgestuurd naar het overzicht van "tag".
- Uitbreidbaarheid: Makkelijk aan te passen voor meerdere vocabularia of andere rollen.
5. Beveiliging en best practices
- Vroege interceptie: Voorkomt dat gevoelige routes worden uitgevoerd door vroeg in het verzoek in te grijpen.
- Rolgebaseerde uitzonderingen: Alleen niet-beheerders worden geblokkeerd.
- Duidelijke verantwoordelijkheden: Routing, gebruikerscontrole en redirect zijn gescheiden voor onderhoudbaarheid.
6. Mogelijke uitbreidingen
- Gebruikmaken van
EntityTypeManagerInterface
om toegang te beperken op basis van specifieke termkenmerken. - Algemenere implementatie met ondersteuning voor meerdere vocabularia en configureerbare redirects via instellingen.
7. Belangrijkste inzichten
- Deze Event Subscriber toont een praktische aanpak voor toegangscontrole in Drupal met behulp van Symfony’s event-architectuur.
- Ideaal om taxonomy-vocabularia te beschermen die alleen door vertrouwde gebruikers beheerd mogen worden.