
Joomla ACL uitgelegd: groepen, toegangsniveaus en rechten
Elke klik in Joomla passeert een onzichtbaar controlepunt. Mag deze bezoeker dit artikel zien? Mag deze redacteur die module wijzigen? Is het toegestaan om via dit API-verzoek inhoud aan te maken? Het systeem dat al deze vragen beantwoordt, is de Access Control List (ACL) van Joomla, en het is een van de krachtigste functies van het CMS, en een van de minst begrepen.
Dit artikel legt uit hoe Joomla ACL echt werkt, van het eerste rechten-dropdownmenu tot de assets-boom in de database. Het behandelt de basis voor eigenaren en redacteuren, praktische rechten-recepten en debugging voor beheerders, en de technische details voor ontwikkelaars die ACL in hun eigen extensies willen gebruiken. Het bouwt voort op het Focus On-artikel over Joomla-gebruikers en gebruikersgroepen, dat accounts, groepen en toegangsniveaus introduceert; hier duiken we diep in de rechten-machinerie zelf.
Joomla vraagt nooit twee keer "wie ben je?". Het vraagt bij elke actie "wat mag je?".
Het doel is eenvoudig: je ACL goed genoeg laten begrijpen om het te ontwerpen, te debuggen en te vertrouwen.
1. De basis
1.1 Drie vragen, drie mechanismen
De toegangscontrole van Joomla beantwoordt drie verschillende vragen met drie verschillende mechanismen. Ze uit elkaar houden is het halve werk:
| Vraag | Mechanisme | Voorbeeld |
|---|---|---|
| Wie is deze gebruiker? | Gebruikersgroepen | "Dit account hoort bij Editors." |
| Wat mag hij zien? | Toegangsniveaus | "Dit menu-item is zichtbaar voor Registered." |
| Wat mag hij doen? | Rechten (acties) | "Editors mogen artikelen in deze categorie bewerken." |
Groepen zijn het fundament: zowel toegangsniveaus als rechten worden altijd aan groepen toegekend, nooit aan individuele gebruikers. Denk je ooit "ik wil deze ene persoon extra rechten geven", dan is het Joomla-antwoord: maak eerst een groep voor die rol.
1.2 Waar je ACL in de back-end inregelt
- Gebruikers → Groepen: de groepenboom.
- Gebruikers → Toegangsniveaus: wie wat kan zien.
- Systeem → Algemene configuratie → Rechten: de sitebrede standaardrechten.
- Het tabblad Opties → Rechten van elke component: rechten op componentniveau.
- Elke categorie en veel items: een eigen tabblad Rechten voor fijnmazige regels.
1.3 Waarom ACL moeilijk voelt
Joomla ACL is niet ingewikkeld omdat het slecht ontworpen is. Het voelt ingewikkeld omdat het gelaagd is: een enkele beslissing "mag Bob dit artikel bewerken?" kan de globale standaarden, de componentregels, de categorieregels, de artikelregels en elke groep waarvan Bob erft betrekken. Zodra je die lagen in de juiste volgorde kunt lezen, wordt het systeem voorspelbaar. Die leesvolgorde is precies wat dit artikel je leert.
Naar boven2. De bouwstenen
2.1 De standaard groepenboom
Een verse Joomla 6-installatie levert negen groepen in een boom. Kinderen erven alles wat hun ouders toegekend krijgen:
Public (id 1)
├─ Guest (9) bezoekers die niet ingelogd zijn
├─ Registered (2) ingelogde gebruikers
│ └─ Author (3) mag artikelen aanmaken
│ └─ Editor (4) mag ook artikelen van anderen bewerken
│ └─ Publisher (5) mag ook publiceren en depubliceren
├─ Manager (6) contentwerk in de backend
│ └─ Administrator (7) backend-beheer, de meeste componenten
└─ Super Users (8) alles, overal
Twee takken zijn belangrijk: de content-tak (Registered → Author → Editor → Publisher) werkt vooral op de frontend, en de beheer-tak (Manager → Administrator) werkt in de backend. Super Users staan erbuiten en hoeven aan niemand verantwoording af te leggen.
Overschat de groep Administrators echter niet. Op een verse installatie kunnen zelfs Administrators de Algemene configuratie niet openen, geen extensies installeren en geen custom field-waarden invullen. De standaardregels in paragraaf 5.2 laten precies zien waarom, en valkuil 13.7 laat zien hoe dit mensen in de praktijk verrast.
2.2 Toegangsniveaus zijn gewoon lijstjes met groepen
Een toegangsniveau is niets meer dan een lijst groepen. De standaardniveaus in de database laten het duidelijk zien (de kolom rules van #__viewlevels bevat groep-ID's):
| Niveau | Groepen erin (ID's) |
|---|---|
| Public | [1] - iedereen. |
| Registered | [6,2,8] - Manager, Registered, Super Users. |
| Special | [6,3,8] - Manager, Author, Super Users. |
| Guest | [9] - alleen bezoekers die niet ingelogd zijn. |
| Super Users | [8]. |
Wanneer je het niveau "Registered" aan een artikel toewijst, controleert Joomla: zit de bezoeker in een van deze groepen, of in een kind ervan? Zo ja, dan is het artikel zichtbaar. Toegangsniveaus regelen alleen zichtbaarheid - ze geven nooit het recht om iets te wijzigen.
2.3 Acties: de werkwoorden van ACL
Rechten zijn opgebouwd uit acties. De standaardset, gedeclareerd door com_content en de meeste andere componenten, leest als een lijst werkwoorden:
| Actie | Geeft het recht om |
|---|---|
core.admin |
De rechten en opties van de component te wijzigen. De "ACL-sleutel" zelf. |
core.options |
De opties van de component te wijzigen, zonder het rechten-tabblad. |
core.manage |
De component uberhaupt in de backend te openen. |
core.create |
Nieuwe items aan te maken. |
core.delete |
Items te verwijderen. |
core.edit |
Elk item te bewerken. |
core.edit.own |
Alleen items te bewerken die je zelf hebt aangemaakt. |
core.edit.state |
Te publiceren, depubliceren, archiveren, naar de prullenbak te sturen. |
core.edit.value |
De waarde van aangepaste velden te wijzigen. |
core.manage.workflow / core.execute.transition |
Publicatie-workflows te beheren en te gebruiken (com_content). |
De site zelf heeft ook login-acties, opgeslagen op de wortel van de rechtenboom: core.login.site, core.login.admin, core.login.api en core.login.offline. Daar wordt beslist "mag deze groep inloggen op de administrator?" - en daarom heeft API-toegang zijn eigen expliciete toestemming nodig.
3. De vier rechtenstatussen
3.1 Wat het dropdownmenu echt betekent
Elk rechten-dropdownmenu in Joomla biedt een klein aantal statussen, en twee ervan lijken meer op elkaar dan ze zijn:
| Status | Betekenis |
|---|---|
| Overgenomen | Geen mening hier. Gebruik wat de ouder (groep of niveau erboven) besloot. |
| Toegestaan | Sta de actie op dit niveau expliciet toe. |
| Geweigerd | Verbied de actie expliciet - en vergrendel die beslissing voor alles eronder. |
| Niet toegestaan (berekend) | Het eindresultaat wanneer niemand ooit "Toegestaan" zei. Geen keuze; een standaard. |
3.2 De gouden regel: geweigerd is definitief
De allerbelangrijkste ACL-regel in Joomla: een expliciet Geweigerd kan op een lager niveau nooit ongedaan worden gemaakt. Als een groep core.edit geweigerd krijgt op een component, kan geen categorieregel, geen itemregel en geen kindgroep dat terugzetten naar toegestaan. Diepere niveaus kunnen alleen verder beperken, nooit heropenen.
Daarom behandelen ervaren Joomla-beheerders "Geweigerd" als een brandbijl achter glas: bijna nooit het juiste gereedschap. De standaardstatus van elke actie is al "Niet toegestaan" - als je een recht simpelweg nooit toekent, kan de gebruiker het niet. Bouw rechten op met Overgenomen en Toegestaan; grijp alleen naar Geweigerd wanneer je een uitzondering moet uitsnijden uit iets dat hoger al toegestaan is.
3.3 Niet toegestaan versus geweigerd
"Niet toegestaan" en "Geweigerd" gedragen zich vandaag hetzelfde (de gebruiker kan het niet) maar morgen compleet anders. "Niet toegestaan" klapt om naar toegestaan zodra een ouder de actie toekent. "Geweigerd" blijft voor altijd geweigerd, wat ouders later ook toestaan. Wanneer je de ACL van een site doorlicht, is elke onnodige "Geweigerd" een toekomstig supportticket.
Naar boven4. De rechtenhierarchie
4.1 Vier niveaus, van boven naar beneden bekeken
Joomla beoordeelt rechten langs een keten van algemeen naar specifiek:
Algemene configuratie (de sitebrede standaarden, per groep)
↓
Component (Opties > Rechten van com_content, com_media, ...)
↓
Categorie (het tabblad Rechten van een categorie; geneste categorieen erven)
↓
Item (het tabblad Rechten van een artikel, een module, ...)
Elk niveau begint met wat het niveau erboven besloot (daar wijst "Overgenomen" naar) en mag zijn eigen Toegestaan of Geweigerd toevoegen. Parallel daaraan erft de groepenboom van oudergroep naar kindgroep. Het uiteindelijke recht van een gebruiker is de combinatie van beide erflijnen: al zijn groepen, over alle niveaus van de hierarchie.
4.2 Waar je wat instelt
Een praktische vuistregel om ACL onderhoudbaar te houden:
- Algemene configuratie: brede rollen. "Managers mogen inloggen op de backend."
- Component: wat een rol mag in een gebied. "Editors mogen artikelen bewerken."
- Categorie: afdelingsgrenzen. "Marketing-redacteuren mogen alleen de categorie Nieuws bewerken."
- Item: zeldzame uitzonderingen. Hoe meer regels op itemniveau, hoe moeilijker je site te doorgronden is.
4.3 De kolom met de berekende instelling
Elk rechten-tabblad toont naast jouw gekozen status een kolom Berekende instelling. Die kolom is de waarheid: hij toont het resultaat nadat alle overerving is toegepast. Wijzig je een dropdownmenu, sla dan eerst op - de berekende kolom wordt pas na het opslaan bijgewerkt. Deze kolom op het juiste niveau lezen beantwoordt de meeste "waarom kan deze gebruiker niet…?"-vragen voordat het echte debuggen begint.
Naar boven5. De assets-boom
5.1 Waar rechten opgeslagen worden
Elk object dat rechten kan dragen - de site zelf, elke component, elke categorie, elk artikel - heeft een rij in de tabel #__assets. De rijen vormen een boom, opgeslagen als nested set (met kolommen lft en rgt) zodat Joomla een hele tak in een query kan ophalen:
root.1 de site (regels van de Algemene configuratie)
├─ com_content de component
│ ├─ com_content.category.14 een categorie
│ │ └─ com_content.article.42 een artikel
└─ com_banners
└─ com_banners.category.3
De asset-name volgt een strak patroon: {component}.{type}.{id}. Wanneer je rechten op een artikel bewerkt, bewerk je de regels van asset com_content.article.42. Wanneer je de rechten in de Algemene configuratie bewerkt, bewerk je root.1.
5.2 Regels zijn JSON
Elke asset-rij heeft een kolom rules met een klein JSON-object: actie → groep-ID → 1 (toestaan) of 0 (weigeren). Echte voorbeelden uit een verse Joomla 6-database:
com_banners:
{"core.admin":{"7":1},"core.manage":{"6":1}}
= Administrators (7) mogen hem configureren,
Managers (6) mogen hem beheren.
root.1 (fragment):
{"core.admin":{"8":1},
"core.manage":{"7":1},
"core.login.site":{"6":1,"2":1},
"core.login.admin":{"6":1},
"core.login.api":{"8":1}}
= alleen Super Users (8) hebben de hoofdsleutel core.admin,
Administrators (7) mogen beheren; Managers en Registered
mogen inloggen op de site, Managers op de backend,
Super Users op de API.
com_installer:
{"core.manage":{"7":0},"core.delete":{"7":0},"core.edit.state":{"7":0}}
= een expliciete 0: core Joomla WEIGERT zelf de groep
Administrators de toegang tot de extensie-installer.
Een leeg object {} betekent "geen mening op dit niveau, erf alles" - en dat is precies wat de meeste categorieen en items zouden moeten hebben. Als je je ooit afvroeg wat het tabblad Rechten echt opslaat: het is deze ene JSON-waarde.
De standaardregels zijn net zo interessant om wat ze niet zeggen. Op root.1 krijgt geen enkele groep core.options, en nergens krijgt een groep core.edit.value (de actie voor custom fields). Omdat niets ze toekent, berekent Joomla ze als "Niet toegestaan (overgenomen)" voor elke groep onder Super Users - Administrators incluis. Daarom ziet een Administrator bij Configure Options "Niet toegestaan", en daarom kunnen op een verse site alleen Super Users custom field-waarden invullen. En com_installer is de ene plek waar core Joomla zelf de brandbijl uit paragraaf 3.2 hanteert: een expliciete weigering die Administrators uit de installer houdt, op geen enkel dieper niveau te veranderen.
5.3 Waarom de assets gezond moet blijven
Omdat assets een nested set vormen, veroorzaakt een beschadigde boom (na mislukte migraties of directe database-bewerkingen) verbijsterende symptomen: rechten die op de verkeerde items van toepassing zijn, categorieen die hun componentregels negeren. De oplossing is de boom opnieuw opbouwen - zie de debug-sectie hieronder.
Naar boven6. Hoe Joomla een recht berekent
6.1 De wandeling
Wanneer code vraagt "mag gebruiker 99 core.edit doen op com_content.article.42?", voert Joomla een vaste wandeling uit:
- Verzamel alle groepen van gebruiker 99, inclusief elke oudergroep hogerop in de boom.
- Laad de regels van de asset en al zijn voorouders: artikel 42 → categorie 14 → com_content → root.1.
- Voeg de regels van boven naar beneden samen. Voor elke actie overschrijft een dieper niveau "Overgenomen" - maar een 0 (weigeren) is plakkerig: zodra een relevante groep een weigering raakt, blijft het samengevoegde resultaat voor die groep weigeren.
- Het uiteindelijke antwoord is alleen ja als minstens een van de groepen van de gebruiker op 1 (toestaan) eindigt en geen enkele op 0 voor die actie... een enkele geweigerde groep torpedeert het geheel.
Dat laatste punt verdient nadruk: een gebruiker met twee groepen krijgt de optelsom van hun toestemmingen, maar elke weigering in welke groep dan ook wint. Een gebruiker aan een extra groep toevoegen kan dus mogelijkheden wegnemen, als die groep een weigering draagt. Dit verrast bijna iedereen een keer.
6.2 De Super User-uitzondering
Een controle gebeurt voor dit alles. Als een van de groepen van de gebruiker core.admin toegestaan heeft op de root-asset, is de gebruiker een Super User, en antwoordt authorise() ja op alles zonder de boom te doorlopen. Dit is ook waarom "Super Users" geen magische hard-gecodeerde groep is: elke groep waaraan je core.admin op het niveau van de Algemene configuratie toekent, wordt een super-user-groep. Ken het met grote voorzichtigheid toe.
Er is nog een achterdeur, met opzet: de instelling root_user in configuration.php kan een account aanwijzen als nood-Super User, onafhankelijk van welke groep dan ook. Joomla's eigen code controleert het als vangnet. Ben je ooit buitengesloten van een site, dan is dit het officiele reddingsluik - en vind je het ingesteld op een site die je overneemt, vraag dan waarom.
6.3 Gasten worden ook berekend
Een bezoeker die niet ingelogd is, staat niet buiten het systeem. Hij wordt behandeld als lid van de groep Guest (daarom bestaat het toegangsniveau Guest), en dezelfde wandeling geldt. "Publieke" content is simpelweg content waarvan het toegangsniveau de groep Public bevat waar iedereen, inclusief gasten, bij hoort.
Naar boven7. ACL-recepten uit de praktijk
7.1 Een afdeling die alleen haar eigen categorie beheert
Doel: het marketingteam bewerkt artikelen in de categorie Nieuws en nergens anders.
- Maak groep Marketing met ouder Registered (niet Editor - je kent rechten expliciet toe).
- Laat in com_content → Opties → Rechten Marketing overal op Overgenomen staan.
- Open de categorie Nieuws → Rechten, en zet voor Marketing: Aanmaken = Toegestaan, Bewerken = Toegestaan, Status bewerken = Toegestaan.
- Wijs de marketing-gebruikers toe aan de groep Marketing.
Omdat de toestemmingen op de categorie-asset staan, gelden ze voor die categorie en haar kinderen - en verder nergens. Nergens een weigering nodig.
7.2 Een contentmanager die alleen de frontend gebruikt
Doel: een klantcontact dat artikelen kan aanmaken, bewerken en publiceren vanaf de frontend, maar nooit de backend ziet.
- Maak groep Content Manager onder Registered.
- Sta in de rechten van com_content Aanmaken, Bewerken en Status bewerken toe voor de groep.
- Ken nergens
core.login.admintoe. Zonder de backend-login-actie bestaat de backend simpelweg niet voor hen.
7.3 Een gedeelte alleen voor leden
Doel: betalende leden zien premium content; alle anderen zien een teaser.
- Maak groep Leden onder Registered.
- Maak toegangsniveau Premium met daarin Leden (en, bewust, Super Users - zie de valkuilen hieronder).
- Zet de premium artikelen, modules en menu-items op niveau Premium.
Merk op dat er helemaal geen rechten zijn aangeraakt: pure zichtbaarheidsproblemen hebben alleen groepen en toegangsniveaus nodig. Hier naar het tabblad Rechten grijpen zou over-engineering zijn.
7.4 Een strak afgeschermde API-integratiegebruiker
Doel: een extern systeem plaatst artikelen via de Web Services API met zo min mogelijk macht.
- Maak groep API Writer onder Registered.
- Algemene configuratie → Rechten: sta Site API-login (
core.login.api) toe voor de groep. - Rechten van com_content: sta Aanmaken toe (en niets anders) voor de groep.
- Maak een gebruiker aan in alleen deze groep, schakel een API-token voor hem in, en laat de integratie dat token gebruiken.
Lekt het token ooit, dan kan de aanvaller ongepubliceerde artikelen aanmaken - en dat is alles.
Naar boven8. Rechten debuggen
8.1 De ingebouwde rechten-debugger
Weinig mensen weten dat Joomla een ACL-debugger meelevert. Open in Gebruikers → Beheren de acties voor een gebruiker en kies Debug gebruiker (er is een bijpassende Debug groep voor groepen). Je krijgt een volledige matrix: elke asset op de site tegen elke actie, met precies waar elk recht vandaan komt - expliciet toegestaan, verboden of overgenomen. Wanneer een rechtenpuzzel de berekende-instelling-kolom weerstaat, is deze weergave je microscoop.
8.2 Een leesvolgorde voor "gebruiker X kan Y niet"
- Welke groepen heeft de gebruiker echt? (Controleer het bewerkformulier; vergeet niet dat oudergroepen meetellen.)
- Is het een zichtbaarheidsprobleem (toegangsniveau) of een rechtenprobleem (actie)? Ze falen verschillend: onzichtbaar versus "niet geautoriseerd".
- Loop de hierarchie van boven naar beneden: Algemeen → component → categorie → item, en lees de berekende kolom voor de groepen van de gebruiker.
- Jaag op een expliciet Geweigerd in welke groep van de gebruiker dan ook, op welk niveau dan ook. Een is genoeg om alles te torpederen.
- Nog steeds vast? Open Debug gebruiker en lees de rij voor de exacte asset.
8.3 Direct in de database kijken
Drie query's beantwoorden de meeste forensische vragen:
-- Welke regels draagt een asset?
SELECT name, rules FROM #__assets
WHERE name = 'com_content.category.14';
-- Welke assets dragen een expliciete weigering (waarde 0)?
SELECT name, rules FROM #__assets
WHERE rules LIKE '%:0%';
-- Bij welke groepen hoort een gebruiker?
SELECT g.title FROM #__usergroups AS g
JOIN #__user_usergroup_map AS m ON m.group_id = g.id
WHERE m.user_id = 99;
8.4 De assets-boom opnieuw opbouwen
Gedragen rechten zich onzinnig na een migratie of een vastgelopen import, bouw dan de nested set opnieuw op: de knop Gebruikers → Groepen → Opnieuw opbouwen herbouwt de groepenboom, en voor de assets-tabel zit een vergelijkbare reparatie in de database-gereedschappen (Systeem → Database → Structuur bijwerken repareert veel asset-problemen). Bewerk nooit met de hand lft/rgt-waarden.
9. Onder de motorkap (ontwikkelaarsblik)
9.1 De betrokken tabellen
| Tabel | Rol |
|---|---|
#__assets |
De rechtenboom: een rij per object met rechten, regels als JSON. |
#__usergroups |
De groepenboom (ook een nested set). |
#__user_usergroup_map |
Welke gebruiker in welke groepen zit (veel-op-veel). |
#__viewlevels |
Toegangsniveaus, elk met een JSON-array van groep-ID's. |
9.2 De Access-klasse
Alle berekening woont in Joomla\CMS\Access\Access, met Rules en Rule als de waarde-objecten die de JSON samenvoegen. De methoden die je echt zult gebruiken:
use Joomla\CMS\Access\Access;
Access::check($userId, 'core.edit', 'com_content.article.42');
Access::checkGroup($groupId, 'core.manage', 'com_content');
Access::getAuthorisedViewLevels($userId); // bijv. [1, 2, 5]
Access::getGroupsByUser($userId); // inclusief geerfde ouders
Access::preload('com_content'); // warm de cache op voor een component
In alledaagse componentcode roep je Access zelden direct aan; je vraagt het aan het gebruikersobject, dat delegeert en cachet:
$user = $this->getUserFactory()->loadUserById($userId);
if ($user->authorise('core.edit.state', 'com_content.article.42')) {
// mag dit artikel publiceren of depubliceren
}
9.3 Lijsten filteren op toegangsniveau
Rechtencontroles bewaken acties; toegangsniveaus bewaken query's. Elke core contentquery filtert op de niveaus van de gebruiker, en die van jou zou dat ook moeten doen:
$levels = $user->getAuthorisedViewLevels();
$query->whereIn($db->quoteName('a.access'), $levels);
Dit filter vergeten is hoe "verborgen" content weglekt naar aangepaste modules en zoekresultaten: het item was beschermd, maar de query heeft het nooit gevraagd.
9.4 Prestaties: een boom, goed gecachet
ACL oogt duur - een JSON-samenvoeging over een boom bij elke controle - maar Joomla cachet agressief per request: de groepen van de gebruiker, de asset-regels en elk authorise()-oordeel worden een keer berekend. Het praktische advies: roep Access::preload() aan wanneer je weet dat je veel items van een component gaat controleren, en loop nooit duizend items langs met telkens een verse controle op koude caches.
10. ACL in je eigen extensie
10.1 Declareer je acties: access.xml
Een component kondigt aan welke acties hij ondersteunt in een bestand access.xml in zijn admin-hoofdmap. Een minimale, realistische vorm (dit weerspiegelt wat com_content meelevert, dat extra secties declareert voor categorieen, artikelen, velden en workflow-stadia):
<?xml version="1.0" encoding="UTF-8"?>
<access component="com_example">
<section name="component">
<action name="core.admin" title="JACTION_ADMIN" />
<action name="core.manage" title="JACTION_MANAGE" />
<action name="core.create" title="JACTION_CREATE" />
<action name="core.delete" title="JACTION_DELETE" />
<action name="core.edit" title="JACTION_EDIT" />
<action name="core.edit.state" title="JACTION_EDITSTATE" />
</section>
<section name="item">
<action name="core.edit" title="JACTION_EDIT" />
<action name="core.edit.state" title="JACTION_EDITSTATE" />
</section>
</access>
Je bent niet beperkt tot de standaardset. Een component kan eigen acties declareren - een goedkeuringsrecht, een exportrecht - en ze net als elk ander recht controleren. Geef eigen acties je eigen prefix en laat core. aan de standaardset:
<action name="example.approve" title="COM_EXAMPLE_ACTION_APPROVE" />
if ($user->authorise('example.approve', 'com_example')) {
// deze gebruiker mag items goedkeuren
}
De eigen actie verschijnt automatisch in het tabblad Rechten naast de standaardacties, en beheerders kennen haar per groep toe zoals elke andere actie. Zo bouw je beoordelings-workflows, exportrechten en vergelijkbare rolspecifieke mogelijkheden zonder een eigen rechtensysteem te verzinnen.
10.2 Toon het rechten-tabblad: config.xml
Het vertrouwde tabblad Rechten verschijnt in de Opties van je component zodra zijn config.xml het rules-veld bevat:
<fieldset name="permissions" label="JCONFIG_PERMISSIONS_LABEL">
<field name="rules" type="rules"
label="JCONFIG_PERMISSIONS_LABEL"
component="com_example"
section="component" />
</fieldset>
Joomla leest de secties en acties uit je access.xml (via Access::getActionsFromFile()) en rendert de hele matrix voor je.
10.3 Assets per item krijg je bijna cadeau
Als je item-tabel Joomla's Table-klasse uitbreidt en een kolom asset_id heeft, maakt en onderhoudt het framework de asset-rij bij het opslaan: het berekent de asset-naam (com_example.item.7), vindt de ouder-asset en slaat de regels uit het rechten-veld op. Jouw taak is alleen de juiste asset-naam te controleren in je controllers en views, op het diepste niveau dat bestaat:
$assetName = 'com_example.item.' . (int) $item->id;
if (!$user->authorise('core.edit', $assetName)) {
throw new \Exception(Text::_('JERROR_ALERTNOAUTHOR'), 403);
}
Onthoud de les uit het artikel over security hardening: een werkbalkknop verbergen is cosmetica. De authorise()-aanroep in de code is de echte bescherming.
11. ACL en de Web Services API
11.1 Dezelfde regels, geen uitzonderingen
De Web Services API heeft geen eigen rechtensysteem. Een API-verzoek authenticeert als een gebruiker (meestal via een token), en vanaf dat moment dwingt elk endpoint exact dezelfde ACL af als de website: dezelfde groepen, dezelfde assets, dezelfde weigerregels. Er is precies een extra poort: de groep heeft core.login.api toegestaan nodig op het niveau van de Algemene configuratie, anders faalt de authenticatie voordat er ook maar een endpoint draait.
11.2 ACL beheren via de API
Gebruikers, groepen en toegangsniveaus zijn zelf ook via REST te beheren:
curl -H "X-Joomla-Token: <token>" \
https://example.test/api/index.php/v1/users
curl -H "X-Joomla-Token: <token>" \
https://example.test/api/index.php/v1/users/groups
curl -H "X-Joomla-Token: <token>" \
https://example.test/api/index.php/v1/users/levels
Alle drie ondersteunen de gebruikelijke CRUD-werkwoorden, dus provisioning-tools kunnen groepen en niveaus programmatisch aanmaken. Behandel deze endpoints met respect: wie naar v1/users/groups kan POSTen, kan je hele rechtenmodel omvormen. Houd API-toegang beperkt tot speciale, minimale accounts, precies zoals in het recept in sectie 7.4.
12. SEO en metadata
ACL heeft een stille maar echte relatie met SEO. Content achter een toegangsniveau is onzichtbaar voor zoekmachine-crawlers, die als gast browsen: een pagina op Registered bestaat simpelweg niet voor Google. Dat is meestal de bedoeling - maar het betekent ook dat een onbedoelde wijziging van het toegangsniveau in stilte een hele sectie uit de index kan halen. Stort het verkeer van een pagina in, dan kost het controleren van haar toegangsniveau tien seconden en heeft het meer "SEO-mysteries" opgelost dan welke meta-tag dan ook.
De omgekeerde fout komt ook voor: teaser-pagina's die voor iedereen bedoeld zijn erven per ongeluk een beperkt niveau van een menu-item of oudercategorie, of een aangepaste module lekt premium content naar publieke zoekresultaten omdat haar query het toegangsniveau-filter vergat (sectie 9.3). Controleer na elke ACL-wijziging die publieke delen raakt wat een uitgelogde bezoeker - en dus een crawler - echt kan zien.
Naar boven13. Veelvoorkomende fouten en valkuilen
13.1 Geweigerd gebruiken waar niet toegestaan al werkt
Symptoom: maanden later kan een groep op mysterieuze wijze iets niet, wat je ook toestaat.
Oplossing: onthoud dat weigeren definitief is, de hele boom naar beneden. Doorzoek de site op expliciete weigeringen (de SQL in sectie 8.3 vindt ze) en vervang ze door gewoon "Overgenomen" waar de standaard "Niet toegestaan" het werk al doet.
13.2 Een extra groep neemt rechten weg
Symptoom: je voegt een gebruiker toe aan een tweede groep om meer toegang te geven, en hij verliest juist mogelijkheden.
Oplossing: een van de regels van de nieuwe groep draagt een weigering, en elke weigering onder de groepen van een gebruiker torpedeert de toestemmingen van de andere. Bekijk beide groepen in Debug gebruiker en verwijder de weigering.
13.3 Super Users vergeten in een eigen toegangsniveau
Symptoom: beheerders melden dat premium content "weg" is terwijl leden haar prima zien.
Oplossing: toegangsniveaus bevatten alleen de groepen die jij erin stopt - Super Users omzeilen rechten, niet toegangsniveaus. Voeg de groep Super Users toe aan elk eigen niveau.
13.4 core.admin achteloos toekennen
Symptoom: een "content"-groep kan opeens rechten wijzigen, of erger, is een volwaardige super-user-groep geworden.
Oplossing: core.admin op een component geeft de ACL van die component uit handen; op de Algemene configuratie maakt het Super Users. Ken het bijna nooit toe, en controleer wie het vandaag heeft.
13.5 Zichtbaarheidsproblemen oplossen met rechten
Symptoom: een kluwen van rechtenregels op itemniveau die alleen maar content voor sommige bezoekers moest verbergen.
Oplossing: zichtbaarheid is het werk van toegangsniveaus; rechten zijn voor acties. Bevat de eis het woord "zien", denk dan eerst aan niveaus.
13.6 Directe database-bewerkingen zonder opnieuw opbouwen
Symptoom: na het importeren van content of het bewerken van groepen in SQL gelden rechten voor de verkeerde dingen.
Oplossing: zowel #__assets als #__usergroups zijn nested sets waarvan de lft/rgt-waarden consistent moeten blijven. Gebruik de knop Opnieuw opbouwen onder Gebruikers → Groepen en de database-reparatiegereedschappen, en vermijd het met de hand bewerken van boomtabellen helemaal.
13.7 Verwachten dat Administrators bijna Super Users zijn
Symptoom: een gebruiker in de groep Administrators kan de Algemene configuratie niet openen, kan geen extensies installeren en ziet in het artikel-bewerkscherm elk custom field grijs - de tabbladen Rechten tonen overal "Edit Custom Field Value" als "Niet toegestaan (overgenomen)", ook op elk nieuw aangemaakt veld.
Oplossing: er is niets kapot; dit zijn de meegeleverde standaardinstellingen (paragraaf 5.2). root.1 geeft Administrators alleen core.manage, core.admin is exclusief voor Super Users, com_installer bevat een expliciete weigering voor groep 7, en geen enkele groep krijgt core.edit.value. Ken bewust toe wat je beheerders echt nodig hebben: zet Edit Custom Field Value op Toegestaan op componentniveau (bijvoorbeeld Content → Artikelen → Opties → Rechten), zodat alle velden het overerven. Moeten Administrators ook extensies installeren, dan moet een Super User de expliciete weigering op com_installer zelf vervangen (Systeem → Installeren → Extensies, daarna Opties → Rechten) - onthoud uit paragraaf 3.2 dat geen enkele diepere toestemming die ooit kan overrulen.
14. Best practices
Als je maar een paar dingen uit dit artikel onthoudt, onthoud dan deze:
- Ken rechten toe aan groepen, denk nooit in individuele gebruikers; maak een groep per rol, niet per persoon.
- Bouw op met Toegestaan en Overgenomen; behandel Geweigerd als laatste redmiddel, want het is definitief tot helemaal onderaan.
- Stel rechten zo hoog mogelijk in de hierarchie in - algemeen voor rollen, component voor gebieden, categorie voor afdelingen - en houd regels op itemniveau zeldzaam.
- Gebruik toegangsniveaus voor "wie ziet dit" en rechten voor "wie doet dit"; vermeng de twee taken niet.
- Voeg Super Users toe aan elk eigen toegangsniveau dat je maakt.
- Houd de kring van
core.admin-houders (en dus Super Users) zo klein mogelijk, en geef API-integraties hun eigen minimale groep. - Controleer na elke ACL-wijziging als de betrokken gebruiker - de weergave Debug gebruiker of een testaccount vertelt de waarheid.
- Ontwikkelaars: declareer acties in
access.xml, controleerauthorise()op de diepste asset, en filter elke query op toegangsniveaus.
15. In het kort
MODEL groepen = wie je bent (#__usergroups, nested)
niveaus = wat je kunt ZIEN (#__viewlevels, lijst groep-id's)
acties = wat je kunt DOEN (rules-JSON op #__assets)
STATUSSEN Overgenomen geen mening, vraag de ouder
Toegestaan hier toekennen
Geweigerd hier verbieden - DEFINITIEF, wint van elke
toestemming eronder
Niet toegestaan het standaardresultaat zonder toekenning
HIERARCHIE root.1 (Algemene configuratie) > component > categorie > item
groepenboom erft parallel; elke weigering torpedeert
ASSETS naampatroon: com_content.article.42
rules: {"core.edit":{"4":1}} actie > groep > 1/0
SUPER USER elke groep met core.admin toegestaan op root.1
omzeilt rechten, NIET toegangsniveaus
noodgeval: root_user in configuration.php
ADMINS (7) standaard: core.manage op root.1, meeste componenten
GEEN Algemene configuratie (core.admin = alleen 8)
GEEN extensie-installer (com_installer weigert 7)
GEEN custom field-waarden (core.edit.value nooit toegekend)
DEBUG kolom berekende instelling (eerst opslaan, dan lezen)
Gebruikers > Beheren > Debug gebruiker / Debug groep
SELECT name, rules FROM #__assets WHERE rules LIKE '%:0%';
RECEPTEN afdeling: toestaan op alleen hun categorie
frontend mgr: contentrechten, geen core.login.admin
ledengedeelte: groep + toegangsniveau, geen rechten
API-gebruiker: eigen groep, core.login.api + een actie
API v1/users, v1/users/groups, v1/users/levels
API-verzoeken volgen normale ACL + core.login.api-poort
DEV access.xml declareert acties
<field type="rules"> toont het tabblad
$user->authorise('core.edit', $assetName)
filter query's op getAuthorisedViewLevels()
Naar boven16. Samenvatting
Joomla's ACL is een gelaagd maar consistent systeem:
- Drie mechanismen beantwoorden drie vragen: groepen (wie je bent), toegangsniveaus (wat je ziet), rechten (wat je doet).
- Vier statussen sturen elk dropdownmenu, en de gouden regel is dat een expliciet Geweigerd definitief is voor de hele boom eronder.
- De hierarchie loopt van de Algemene configuratie via component en categorie naar item, opgeslagen als een assets-boom met JSON-regels in
#__assets. - De berekening voegt alle groepen van een gebruiker samen: toestemmingen stapelen, maar een enkele weigering torpedeert, en
core.adminop de root maakt een Super User die de wandeling helemaal overslaat. - De standaardinstellingen zijn strenger dan de meeste mensen verwachten: Administrators krijgen
core.managemaar geen Algemene configuratie, een expliciete weigering op de extensie-installer, en - net als elke groep behalve Super Users - geen recht om custom field-waarden te bewerken. - Debuggen is een leesoefening: de berekende kolom, de weergave Debug gebruiker en drie SQL-query's onthullen elke regel op de site.
- Ontwikkelaars krijgen de hele machine - acties, het rechten-tabblad, assets per item - door een
access.xml, een formulierveld en eerlijkeauthorise()-controles mee te leveren.
Zodra je het mechanisme kunt benoemen waar een eis bij hoort - zien, doen of zijn - is Joomla ACL niet eng meer. De dropdownmenu's worden zinnen die je kunt lezen, en de site wordt een plek waar je kunt bewijzen wie wat mag.
Tegelijk is ACL het deel van Joomla waar een kleine vroege fout jarenlang stilletjes doorgroeit. Heeft jouw site mysterieuze weigeringen verzameld, super-user-groepen waarvan niemand zich herinnert dat ze gemaakt zijn, of rechten-tabbladen waar niemand aan durft te komen, dan brengt een ervaren, gestructureerde ACL-audit - groepen, niveaus, assets en regels, in die volgorde - meestal in een middag zowel duidelijkheid als veiligheid terug. Het is precies het soort werk waar een Joomla-specialist blij van wordt.
Naar boven

Peter is Joomla specialist en Linux admin voor snelle, veilige en schaalbare websites.












