Access Control List implementatie in PHP/MySQL - deel 1/2

Samenvatting

Dit artikel beschrijft een implementatie van een Access Control List (ACL). Uiteraard zijn er legio manieren om dit te doen en ook hoe je dit vervolgens inricht hangt af van hoe je de rechten zelf organiseert.


Deze implementatie zal je in staat stellen om bronnen (resources) uitsluitend toegankelijk te maken voor gebruikers met voldoende rechten. Heel bondig samengevat bereiken we dit door geserialiseerde predicaten (Boolean statements) bij deze bronnen op te slaan in Poolse Notatie. De rest van dit artikel gaat je (hopelijk) duidelijk maken wat dit precies inhoudt.


Allereerst zal er een korte schets gegeven worden van de achterliggende wens om bepaalde onderdelen van je website of applicatie af te schermen en alleen toegankelijk te maken voor bepaalde gebruikers. We gaan er hierbij vanuit dat er al een bepaald loginmechanisme aanwezig is, maar daarna is het zaak dat er een vorm van rechtenbeheer beschikbaar is in je code.


Vervolgens behandelen we wat theorie en formuleren we een generieke oplossing die voortborduurt op deze theorie.


Tot slot, en hier ligt eigenlijk de grootste uitdaging, verkennen we hoe we deze oplossing kunnen omzetten naar een (semi) gebruiksvriendelijke implementatie die redelijk eenvoudig te gebruiken is voor mensen die mogelijk wat minder technisch onderlegd zijn. Uiteraard zullen deze beheerders wel enig verstand moeten hebben van Boolse logica om deze ACL te kunnen gebruiken, maar zoals het spreekwoord gaat, with great power comes great responsibility. Dit laatste onderdeel, wat op zichzelf al redelijk uitgebreid is, zal in een apart blogbericht worden behandeld.


Tevens heb ik ondertussen alweer een ander en mogelijk beter idee om dit concept verder uit te bouwen (no rest for the wicked).


Het Dilemma

Code die je zelf schrijft kan zijn pluspunten hebben, maar het is belangrijk dat je er continu voor waakt dat deze op den duur niet verandert in een compleet incoherente brei. Stel dat je op een zeker moment een soort van rechtenmanagement hebt geïntroduceerd en dat je functionaliteit hebt geprogrammeerd die afgeschermd is door genummerde rechten. Beschouw het volgende stuk code die bepaalt of een geauthenticeerde gebruiker toegang heeft tot de functionaliteit indien voldaan is aan de volgende condities:

  • de gebruiker bezit recht 1
    of
  • de gebruiker bezit recht 2
    maar ook
    • de gebruiker bezit recht 3 niet

Een mogelijke implementatie in pseudo-code wordt dan zoiets als:



PHP Source Code

Edit Source Code

  1. <?php
  2. if (
  3. $user->hasRight(1)
  4. ||
  5. ($user->hasRight(2) && $user->hasRight(3) === false)
  6. ) {
  7. // access granted, do stuff
  8. // ...
  9. } else {
  10. // access denied, complain, redirect, die
  11. // ...
  12. }
  13. ?>


Deze code doet zijn ding, maar heeft een aantal nadelen:

  • de werking ligt vast in de code (hard coded) en is daarmee inflexibel, als je deze permissies wilt wijzigen zul je de code handmatig moeten aanpassen
  • dit belemmert vervolgens de herbruikbaarheid van deze code; stel dat bovenstaande code gebruikt wordt om te bepalen of iemand een stuk tekst mag zien (bijvoorbeeld een artikel); in deze opzet leent deze code zich niet voor het tonen van verschillende artikelen aan verschillende gebruikers op grond van verschillende rechten, tenzij je wellicht een heel lang en gecompliceerd if-statement breit (niet doen lol)

Aldus, een eerste stap richting verbetering van (her)gebruik zou het extraheren van deze check uit de bovenstaande code zijn. Een manier om dit te doen is deze check opslaan bij deze bron. Maar hoe zou zo'n controle er dan uitzien, en hoe zou je deze moeten evalueren? Idealiter zou je deze Boolse uitdrukking (predicaat) willen opslaan in een ondubbelzinnig formaat die makkelijk leesbaar en evalueerbaar is (voor machines). Een daadwerkelijke lap PHP-code opslaan die vervolgens wordt geeval()ueerd is waarschijnlijk geen goed idee (al deed Drupal iets soortgelijks in het verleden geloof ik)... Het predicaat heeft mogelijk een complexe structuur maar volgt uiteraard een zekere logica.


Omdat we op dit moment niet direct een concreet idee hebben hoe we zoiets aanpakken (het vertalen van een predicaat in een soort van structuur) verkennen we de mogelijkheden op een wat abstracter niveau: we maken wat kladtekeningen.


Bouw een Boom

Predicaten hebben structuur. Bomen ook. Is het mogelijk om een predicaat uit te schrijven in een boom? We vervolgen ons eerdere voorbeeld:



PHP Source Code

Edit Source Code

  1. /*
  2. OR-+-1
  3. ...|
  4. ...+-AND-+-2
  5. .........|
  6. .........+-NOT-3
  7. */


Dit ziet er semi zinnig uit. Maar hier is mogelijk nog het probleem van dubbelzinnigheid. Neem bijvoorbeeld A AND B OR C. Afhankelijk van wat je bedoelt mondt dit uit in twee compleet verschillende bomen. Bedoelden we (A AND B) OR C:



PHP Source Code

Edit Source Code

  1. /*
  2. OR-+-C
  3. ...|
  4. ...+-AND-+-A
  5. .........|
  6. .........+-B
  7. */


Of toch A AND (B OR C):



PHP Source Code

Edit Source Code

  1. /*
  2. AND-+-A
  3. ....|
  4. ....+-OR-+-B
  5. .........|
  6. .........+-C
  7. */


En dan is daar nog de variant waarbij meer dan twee condities moeten gelden (A AND B AND C AND D). Een eerste ingeving is wellicht om sub-expressies te groeperen met haken (en een tweede is wellicht om gefrustreerd te vloeken). Dit lost weliswaar het dubbelzinnigheidsprobleem op (de betekenis van het predicaat is eenduidig door het gebruik van haken) maar introduceert wel een ander probleem: het maakt het evalueren van zo'n statement (vele malen) complexer omdat we deze dan waarschijnlijk moeten parsen en / of recursief moeten doorlopen. Dit heeft mogelijk ook een negatieve invloed op performance van de gebruikmaking van deze functionaliteit.


We kunnen deze potentiële slangenkuil vermijden door wat restricties op te leggen aan onze bouwblokken. Een mogelijke ingeving is dat we de AND- en de OR-operatoren precies twee operanden te laten accepten en de NOT-operator op precies één operand te laten acteren. Dit beperkt hopelijk de noodzaak voor het gebruik van haken of maakt dingen op zijn minst wat eenduidiger. Het nadeel van deze aanpak is uiteraard dat wat langere condities mogelijk wat meer genest worden, maar zoals gezegd, we doen dit met het streven om het gebruik van haken te verminderen of mogelijk helemaal uit te bannen. We zouden bijvoorbeeld A AND B AND C AND D als volgt moeten uitschrijven:



PHP Source Code

Edit Source Code

  1. /*
  2. AND-+-A
  3. ....|
  4. ....+-AND-+-B
  5. ..........|
  6. ..........+-AND-+-C
  7. ................|
  8. ................+-D
  9. */


Maar om eerlijk te zijn, als dit de prijs is die betaald moet worden om een of andere haakjes-parsing-hel te vermijden, het zij zo :).


Okay, dus nu hebben we een (wat meer) geformaliseerde (maar nog steeds abstracte) manier om onze predicaten vorm te geven. Maar wat nu? Nu hebben we een manier nodig om dit uit te schrijven in een geserialiseerde vorm zodat we deze bij onze bron kunnen opslaan. Dit formaat moet ook geschikt zijn om snel een true of false terug te geven als deze wordt geëvalueerd tegen een lijst van toegekende rechten om vast te kunnen stellen of een gebruiker toegang heeft tot deze bron of niet. Zou het niet fijn zijn als er zoiets bestond?


Poolse Notatie to the rescue

Gelukkig is dit reeds het geval. De Poose Notatie, of prefix-notatie, is een notatiewijze waarbij operatoren voor de operanden worden geplaatst. De WIKI-pagina legt uit dat wanneer de ariteit van de operatoren vastligt, dat wil zeggen, als het vantevoren bekend is op hoeveel parameters een logisch of wiskundig symbool opereert, dat dit resulteert in een notatiewijze die ondubbelzinnig is en daarom ook (totaal) geen haken nodig heeft. Hier hadden we in de vorige paragraaf al op aangestuurd. Tevens beschrijft deze WIKI-pagina een simpel algoritme hoe je een expressie in Poolse Notatie zou moeten evalueren!


Maar even alles in de goede volgorde. Hoe herschrijven we onze boom om naar de Poolse Notatie? De makkelijkste manier is om de boom terug te lezen van de bodem naar de top om vervolgens de expressie van rechts naar links op te bouwen. Als we dit toepassen op ons oorspronkelijke voorbeeld, gemakshalve hier herhaald:



PHP Source Code

Edit Source Code

  1. /*
  2. OR-+-1
  3. ...|
  4. ...+-AND-+-2
  5. .........|
  6. .........+-NOT-3
  7. */


Zou dit moeten resulteren in:



Source Code

Edit Source Code

  1. OR 1 AND 2 NOT 3



Dit volgt weliswaar exact de boomstructuur, maar het is handig(er) om in eerste instantie deze structuren te leren lezen vanuit de Poolse-Notatie-optiek. Het kan helpen om de WIKI-pagina door te lezen om hier een gevoel voor te krijgen.


De bovenstaande expressie is nog steeds een beetje lijvig, deze kan korter. Een verkorte syntax is bijvoorbeeld als volgt (je kunt deze zelf aanpassen en/of uitbreiden met meer operatoren als je dat leuk vindt):

  • voor de logische AND gebruiken we een ampersand ( & )
  • voor de logische OR gebruiken we een pipe ( | )
  • voor de negatie NOT gebruiken we een uitroepteken ( ! )
  • om alle operatoren en operanden te scheiden gebruiken we een komma ( , )

Ons eerste geserialiseerde predicaat in Poolse Notatie wordt aldus:



Source Code

Edit Source Code

  1. |,1,&,2,!,3


Waarschijnlijk realiseer je je (nog) niet hoe extreem vet het bovenstaande eigenlijk is.


Gas Op De Plank

Laten we aan de slag gaan met programmeren. Wat moet er allemaal gebeuren? Er zijn een aantal zaken die geregeld moeten worden:

  • het bouwen, valideren en opslaan van geldige expressies
  • het evalueren van expressies tegen een lijst van toegekende rechten

Laten we voor nu doen alsof de eerste stap al is gelukt (dit wordt in het volgende deel volledig behandeld, maak je geen zorgen) en we hebben deze expressie ergens opgeslagen en we willen deze nu evalueren tegen rechten die in het bezit van onze gebruiker zijn. We hebben dus een soort functie nodig die het volgende regelt:



PHP Source Code

Edit Source Code

  1. <?php
  2. function isAllowed($expression, $rights) {
  3. // do magic
  4. }
  5. ?>


Deze functie retourneert simpelweg een Boolean (true of false) die aangeeft of een gebruiker met de rechten $rights (een array) toegang heeft tot de bron die is afgeschermd met het predicaat $expression (een logische-boom-in-geserialiseerde-vorm-volgens-Poolse-Notatie). Hoe voeren we deze toverspreuk precies uit? De WIKI-pagina beschrijft het algoritme om dit te doen:



Source Code

Edit Source Code

  1. scan the given prefix expression from right to left
  2. for each symbol {
  3. if operand then
  4. push onto stack
  5. if operator then {
  6. operand1=pop stack
  7. operand2=pop stack
  8. compute operand1 operator operand2
  9. push result onto stack
  10. }
  11. }
  12. return top of stack as result


Dit kan bijna één-op-één vertaald worden naar PHP. Het makkelijkste is waarschijnlijk om eerst het eindresultaat te presenteren en vervolgens uit te leggen wat er gebeurt, en waarom het zo gebeurt.




PHP Source Code

Edit Source Code

  1. <?php
  2. function isAllowed($expression, $rights) {
  3. if ($expression == '') {
  4. return true;
  5. }
  6. $stack = array();
  7. foreach (array_reverse(explode(',', $expression)) as $token) {
  8. if ($token == '&' || $token == '|') {
  9. $val1 = array_pop($stack);
  10. $val2 = array_pop($stack);
  11. $stack[] = ($token == '|' ? $val1 || $val2 : $val1 && $val2);
  12. } elseif ($token == '!') {
  13. $n = count($stack) - 1;
  14. $stack[$n] = !$stack[$n];
  15. } else {
  16. $stack[] = !empty($rights[$token]);
  17. }
  18. }
  19. return $stack[0];
  20. }
  21. ?>



Laten we deze code in stukken opdelen en in afzondering behandelen. Merk hierbij op dat de bovenstaande code opereert onder de aanname dat $expression een geldige geserialiseerde Boolse expressie in Poolse Notatie is, hier zul je dus op een andere plaats zorg voor moeten dragen.



PHP Source Code

Edit Source Code

  1. <?php
  2. if ($expression == '') {
  3. return true;
  4. }
  5. ?>


Dit is redelijk rechttoe rechtaan: indien $expression leeg is wil dit zeggen dat er geen speciale rechten nodig zijn om toegang te verkrijgen tot de bron, met andere woorden, iedereen heeft toegang tot deze bron. In dit geval retourneren we meteen true onafhankelijk van de rechten $rights die deze gebruiker mogelijk heeft. In dit geval is dat namelijk niet relevant.


Voor het doorgronden van het volgende stuk code is het volgende belangrijk. We dienen $stack te zien als een reeks van Boolse (tussen)resultaten van berekeningen. Wanneer we $expression doorlopen slaan we het (tussen)resultaat van reeds ge-evalueerde operatoren en operanden op als Boolse waarden (true of false) in $stack. Afhankelijk van wat we tegenkomen in $expression (een operator of een recht) kan het ook gebeuren dat we reeds opgeslagen waarden weer van de $stack halen en hercombineren tot een nieuw (Bools) resultaat wat we hier weer in opslaan. Dit heeft tot resultaat dat de $stack tijdens de evaluatie van $expression groeit en slinkt. Het algoritme werkt zodanig dat zodra we de hele $expression hebben doorlopen er één enkele (Boolse) waarde over is gebleven op de $stack. Dit is het eindresultaat van de evaluatie van $expression tegen de gebruikersrechten $rights. Deze enkele waarde geeft uiteindelijk aan of iemand toegang zou moeten krijgen tot de bron of niet.


Wat je mee zou moeten nemen van de vorige paragraaf is het volgende: $stack is een array van Boolse waarden. Wanneer $expression volledig is geanalyseerd bevat dit array precies één waarde die aangeeft of de gebruiker voldoende rechten voor toegang had.



PHP Source Code

Edit Source Code

  1. <?php
  2. foreach (array_reverse(explode(',', $expression)) as $token) {
  3. // ...
  4. }
  5. ?>


In deze loop converteren we $expression (een string) naar een array. Hierbij draaien we ook de volgorde van de elementen om. Dit is vanwege de manier waarop de Poolse Notatie zaken inleest: van rechts naar links. Dit stelt ons in staat om elk token waar $expression uit bestaat in afzondering te behandelen. Elk $token bevat ofwel een operator (& (AND), | (OR) of ! (NOT)) of een operand (het id wat een recht representeert die nodig is voor toegang tot de resource).



PHP Source Code

Edit Source Code

  1. <?php
  2. if ($token == '&' || $token == '|') {
  3. $val1 = array_pop($stack);
  4. $val2 = array_pop($stack);
  5. $stack[] = ($token == '|' ? $val1 || $val2 : $val1 && $val2);
  6. } elseif ($token == '!') {
  7. $n = count($stack) - 1;
  8. $stack[$n] = !$stack[$n];
  9. } else {
  10. $stack[] = !empty($rights[$token]);
  11. }
  12. ?>


In dit stuk code wordt het meeste werk verzet. We maken hier onderscheid tussen de verschillende tokens die we tegen kunnen komen:

  • een logische AND ( & ) of een logische OR ( | ),
  • een negatie ( ! ),
  • of (in het else { ... } blok) het id van een recht

Het is waarschijnlijk het makkelijkste om in het else { ... } deel te beginnen. In dit onderdeel inspecteren of het huidige token - dat een recht id bevat - voorkomt in het array van rechten (van een specifieke gebruiker). Hierbij gaan we er vanuit dat $rights een array is van toegekende rechten waarbij de id's van de rechten in de index van het array zitten. Dit zodat we snel kunnen bepalen of een recht aanwezig is in een array, dit in tegenstelling tot een variant waarin de de id's simpelweg in de waarden van een array staan en je in_array() zou moeten gebruiken om te kijken of een recht aanwezig is. Nu ik er over nadenk, wellicht is array_key_exists($token, $rights) of isset($rights[$token]) wellicht beter dan !empty($rights[$token]), in dit laatste geval is het wel zaak dat de waarden van dit array ongelijk zijn aan NULL, anders levert isset() alsnog false op. Welke variant je ook kiest, het $rights array zou er dus ongeveer zo uit moeten zien, merk hierbij op dat dit array uitsluitend toegekende rechten zou moeten bevatten:



PHP Source Code

Edit Source Code

  1. <?php
  2. $myRights = array(
  3. 1 => true,
  4. 2 => true,
  5. 5 => true,
  6. );
  7. ?>


Dus op het moment dat een gebruiker het geïnspecteerde recht bezit voegen we true toe bovenop de $stack, en anders false. We doen dit voor een aantal operanden (rechten) totdat we een operator tegenkomen (ofwel een &, een | of een !).



Indien het token de NOT-operator ( ! ) bevat, veranderen we wat bovenop de $stack staat in de ontkenning hiervan. Als deze waarde gelijk was aan true dan wordt deze false en vice versa. Merk op dat omdat we $expression van rechts naar links lezen en omdat we de operatoren vooraan expressies zetten conform de Poolse Notatie dat dit garandeert dat we altijd eerst (ten minste) een operand tegenkomen, wat weer garandeert dat $stack altijd inhoud heeft voordat een operator hierop acteert.


Wanneer het token ofwel de logische AND ( & ) of de logische OR ( | ) bevat halen we de twee bovenste Boolse waarden van $stack. Merk op dat we dit eerder hadden vastgelegd, deze logische operatoren opereren op precies twee operanden. Vervolgens hercombineren we deze twee waarden tot één resultaatwaarde die we weer terugplaatsen op $stack. De evaluatie hiervan volgt de normale regels voor de genoemde logische operatoren. Is het token een logische OR ( | ) dan voeren we in PHP een logische OR-vergelijking uit (met ||) en anders, als het een logische AND betreft, voeren we de logische AND-vergelijking uit (met &&).



PHP Source Code

Edit Source Code

  1. <?php
  2. return $stack[0];
  3. ?>


Nadat we de hele $expression hebben doorlopen is er één Boolse waarde over op de $stack die aangeeft of de toegekende rechten $rights toereikend waren om toegang te verkrijgen tot de resource. Deze Boolse waarde wordt geretourneerd. Merk (nogmaals) op dat $expression een geldige vorm moet hebben om te garanderen dat er uiteindelijk maar één waarde op de $stack overblijft. Dus voordat we deze expressie opslaan bij de resource is het zaak dat deze onderworpen wordt aan een grondige validatie. We zullen dit later nader bestuderen. Nu eerst een werkend voorbeeld!


Laten we wat rechten-combinaties bekijken om tegen te valideren. We gebruiken wederom ons oorspronkelijke voorbeeld.



PHP Source Code

Edit Source Code

  1. <?php
  2. error_reporting(E_ALL);
  3. ini_set('display_errors', 'stdout');
  4. function isAllowed($expression, $rights) {
  5. if ($expression == '') {
  6. return true;
  7. }
  8. $stack = array();
  9. foreach (array_reverse(explode(',', $expression)) as $token) {
  10. if ($token == '&' || $token == '|') {
  11. $val1 = array_pop($stack);
  12. $val2 = array_pop($stack);
  13. $stack[] = ($token == '|' ? $val1 || $val2 : $val1 && $val2);
  14. } elseif ($token == '!') {
  15. $n = count($stack) - 1;
  16. $stack[$n] = !$stack[$n];
  17. } else {
  18. $stack[] = !empty($rights[$token]);
  19. }
  20. }
  21. return $stack[0];
  22. }
  23. $expression = '|,1,&,2,!,3';
  24. // This should result in access being granted.
  25. $myRights = array(
  26. 1 => true,
  27. );
  28. if (isAllowed($expression, $myRights)) {
  29. echo 'rights: 1. Access granted.<br />';
  30. } else {
  31. echo '[error] rights: 1. Should be granted access!<br />';
  32. }
  33. // This should also result in access being granted.
  34. $myRights = array(
  35. 1 => true,
  36. 2 => true,
  37. );
  38. if (isAllowed($expression, $myRights)) {
  39. echo 'rights: 1, 2. Access granted.<br />';
  40. } else {
  41. echo '[error] rights: 1, 2. Should be granted access!<br />';
  42. }
  43. // Same.
  44. $myRights = array(
  45. 1 => true,
  46. 3 => true,
  47. );
  48. if (isAllowed($expression, $myRights)) {
  49. echo 'rights: 1, 3. Access granted.<br />';
  50. } else {
  51. echo '[error] rights: 1, 3. Should be granted access!<br />';
  52. }
  53. // Same.
  54. $myRights = array(
  55. 2 => true,
  56. );
  57. if (isAllowed($expression, $myRights)) {
  58. echo 'rights: 2. Access granted.<br />';
  59. } else {
  60. echo '[error] rights: 2. Should be granted access!<br />';
  61. }
  62. // This combination is invalid, so access should be denied.
  63. $myRights = array(
  64. 2 => true,
  65. 3 => true,
  66. );
  67. if (isAllowed($expression, $myRights)) {
  68. echo '[error] rights: 2, 3. Access should not be granted!<br />';
  69. } else {
  70. echo 'rights: 2, 3. Access denied.<br />';
  71. }
  72. // Although this is probably an odd combination of granted rights, it should give you access.
  73. $myRights = array(
  74. 1 => true,
  75. 2 => true,
  76. 3 => true,
  77. );
  78. if (isAllowed($expression, $myRights)) {
  79. echo 'rights: 1, 2, 3. Access granted.<br />';
  80. } else {
  81. echo '[error] rights: 1, 2, 3. Should be granted access!<br />';
  82. }
  83. // Yeah... no rights. Good luck.
  84. $myRights = array();
  85. if (isAllowed($expression, $myRights)) {
  86. echo '[error] rights: none. Access should not be granted!<br />';
  87. } else {
  88. echo 'rights: none. Access denied. Shoo!<br />';
  89. }
  90. ?>


Dit produceert vervolgens:



Source Code

Edit Source Code

  1. rights: 1. Access granted.
  2. rights: 1, 2. Access granted.
  3. rights: 1, 3. Access granted.
  4. rights: 2. Access granted.
  5. rights: 2, 3. Access denied.
  6. rights: 1, 2, 3. Access granted.
  7. rights: none. Access denied. Shoo!


Wat we hier uiteindelijk mee hebben bereikt is dat we het volgende:



PHP Source Code

Edit Source Code

  1. <?php
  2. if (
  3. $user->hasRight(1)
  4. ||
  5. ($user->hasRight(2) && !$user->hasRight(3))
  6. ) {
  7. // access granted, do stuff
  8. // ...
  9. } else {
  10. // access denied, complain, redirect, die
  11. // ...
  12. }
  13. ?>



Hebben herschreven naar dit:



Source Code

Edit Source Code

  1. <?php
  2. $expression = '|,1,&,2,!,3';
  3. if (isAllowed($expression, $user->getRights())) {
  4. // access granted, do stuff
  5. // ...
  6. } else {
  7. // access denied, complain, redirect, die
  8. // ...
  9. }
  10. ?>



Waarbij $expression overal vandaan kan komen, deze is niet langer gebonden aan deze code! Mogelijk begin je nu te zien waarom dit zo handig kan zijn.


Tot slot

Im principe heb je nu al de beschikking over een flexibele ACL zonder interface. Theoretisch kun je nu al je resources afschermen door geserialiseerde predicaten in Poolse Notatie in te kloppen. Maar een interface die dit wat verder automatiseert zou wel erg handig zijn. Het volgende deel zal hier verder over uitweiden.


Overigens, een belangrijke realisatie is de volgende: tot nu toe heb ik altijd gesproken over "toegang geven tot", maar wellicht was het beter om dit in een veel algemenere vorm te zien. Een betere omschrijving was wellicht "toestemming tot het uitvoeren van een specifieke actie". Het toegang verlenen tot de resource is slechts één actie. Maar je zou dus meerdere expressies kunnen opslaan bij een resource die aangeven welke rechten(combinaties) je nodig hebt voor het uitvoeren van specifieke acties, zoals toegang (reeds uitvoerig besproken) maar ook het aanmaken, wijzigen of verwijderen van de resource (denk aan CRUD). Voor elk van deze handelingen kun je afzonderlijke rechten- (of rollen-)combinaties definiëren, dit hangt weer helemaal af van hoe je vervolgens je rechten en rollen zelf inricht. Deze ACL stelt je vervolgens in staat om deze makkelijk te managen bij het daadwerkelijk gebruik bij toepassing op concrete situaties zonder inhoudelijke impact op de bijbehorende code.


Het volgende deel zal verder uitweiden over het valideren van de vorm van de expressie zelf, zodat gegarandeerd kan worden dat er enkel geldige expressies worden opgeslagen bij de bron. Ook zal er een simpele implementatie gegeven worden voor een formulier-element, die wat grafischer en intuïtiever is in het gebruik dan het inkloppen van rauwe geserialiseerde predicaten :).


Aan het einde zal tevens een implementatie gegeven worden in MySQL in de vorm van een MySQL-functie. Dit zodat je resultaten op voorhand op grond van gebruikersrechten kunt filteren.


In die blog zal mogelijk ook een schot voor de boeg gegeven worden hoe e.e.a. nog flexibeler (maar ook gebruiksvriendelijker) gemaakt zou kunnen worden, maar dat is nog een beetje een work-in-progress op dit moment.