Skip to main content

Rollen, permissies, context en autorisatie

2.1 Doel

OefenHub gebruikt vanaf Feature 11-5 een permission-based RBAC-model. Rollen blijven bestaan, maar een rol is niet langer het directe autorisatiebewijs voor routes, schermen, menu-items, frontpageblokken of domeinacties.

Dit hoofdstuk beschrijft daarom het onderscheid tussen:

  • gebruikersaccount;
  • roltoekenning;
  • permissions;
  • rol-permissiekoppelingen;
  • samengestelde frontpage- en navigatiecontext;
  • relatiecontext;
  • niveau-, leerling-, kind-, oefening- of beheercontext;
  • zichtbare navigatie;
  • feitelijke server-side autorisatie.

De kernregel is:

Een gebruiker mag een functie alleen gebruiken wanneer de gebruiker de vereiste permission heeft én de actuele server-side domein-/objectcontext geldig is.

Clientstate, routeparameters, zichtbare knoppen, oude browserselecties, bookmarks, filters en lokale UI-state mogen nooit autorisatie afdwingen of verruimen.

2.2 Account, rol, permissie en context

OefenHub onderscheidt vijf lagen.

LaagBetekenis
AccountHet interne Users-record dat de OefenHub-gebruiker representeert en via ExternalId gekoppeld is aan de identity provider.
RoltoekenningEen actieve koppeling tussen gebruiker en rol via UserRoles.
PermissionEen expliciete technische toestemming met code volgens <resource>.<action>[.<scope>], bijvoorbeeld student-results.read.assigned.
Rol-permissiekoppelingEen actieve koppeling tussen rol en permission via RolePermissions.
Domein-/objectcontextDe server-side geldige context voor het concrete object, zoals eigen run, toegewezen leerling, gekoppeld kind, niveau-eigenaarschap of supportflow.

Een gebruiker met een actieve rol heeft dus alleen de permissions die via actieve rollen gekoppeld zijn. Zelfs met een permission is objecttoegang niet automatisch onbeperkt.

Voorbeelden:

  • een gebruiker met student-results.read.assigned mag alleen resultaten lezen van leerlingen die binnen de actuele docentcontext vallen;
  • een gebruiker met student-results.read.children mag alleen resultaten lezen van actief gekoppelde kinderen;
  • een gebruiker met frontpage.view.teacher ziet het docentfrontpageblok, maar krijgt daardoor nog geen leerlingresultaten;
  • een gebruiker met administrator-accounts.read.all mag accountinformatie lezen binnen beheercontext, maar geen identity-providercredentials zien;
  • een gebruiker met practice-run.answer.own mag alleen antwoorden in de eigen actieve oefenrun.

2.3 Rollen als bundels

Rollen blijven functioneel relevant, maar niet als directe autorisatiecheck.

RolFunctie in RBACBelangrijke grens
LeerlingBundel voor eigen oefenen, eigen resultaten, eigen geschiedenis, gedeelde oefeningen en leerlingnavigatie.Kan niet gecombineerd worden met Ouder/voogd, Docent, Beheerder, TestDocent of toekomstige Admin-rol.
Ouder/voogdBundel voor ouder-/voogdfrontpage, kinderen, kindresultaten en live meekijken met actief gekoppelde kinderen.Kan geen oefening namens een kind starten, hervatten, beantwoorden, afronden, corrigeren, opnieuw maken of delen.
DocentBundel voor docentfrontpage, onderwijsstructuur, leerlingen, niveauautorisaties, resultaten binnen toegewezen context en live meekijken binnen docentcontext.Ziet leerlingresultaten alleen binnen eigen docent-, niveau- en leerlingcontext.
BeheerderBundel voor applicatiebeheer, accountbeheer, contentbeheer, modules, categorieën, meldingen en supportflows.Beheert niet automatisch rollen, permissies of rol-permissiekoppelingen; dat wordt in Feature 17 story 091 apart uitgewerkt.
TestDocentBundel voor gecontroleerde testmodulecontexten.Niet-publieke rol; alleen relevant waar module- en testcontext dit expliciet toestaan.
Admin / autorisatiebeheerderToekomstige separate bundel voor rollen- en permissiebeheer.Buiten scope van Feature 11-5; exacte naam/code en beheerinterface worden uitgewerkt in story 17-091.

2.4 Niet-combineerbare leerlingrol

De rol Leerling is functioneel niet combineerbaar met Ouder/voogd, Docent, Beheerder, TestDocent of toekomstige Admin-/autorisatiebeheerrollen.

De reden is dat de leerlingfrontend wezenlijk anders werkt dan de overige contexten:

  • leerlingen oefenen zelf;
  • leerlingen hebben een actieve niveaucontext;
  • leerlingen kunnen tijdens een oefenrun niet worden afgeleid door gewone applicatiesignalen;
  • leerlingnavigatie is categorie- en oefengericht;
  • leerlingvoortgang, resultaten en geschiedenis zijn persoonlijk;
  • leerlingacties mogen niet vermengd worden met beheer-, docent-, ouder- of autorisatiebeheeracties.

Wanneer een natuurlijke persoon ook docent, ouder/voogd, beheerder of autorisatiebeheerder moet zijn, hoort dat niet via hetzelfde account met leerlingrol te gebeuren.

2.5 Combineerbare rollen en samengestelde UI

De rollen Ouder/voogd, Docent en Beheerder mogen gecombineerd voorkomen binnen één account.

Bij combinatierollen geldt:

  • de effectieve permissions zijn de distinct union van alle actieve permissions uit alle actieve rollen;
  • de frontpage wordt runtime samengesteld uit permissiongedreven blokken;
  • menu-items en profielmenu-items worden zichtbaar op basis van permissions, niet op basis van rolchecks;
  • navigatie-items worden niet dubbel getoond;
  • de volgorde van frontpageblokken volgt een vaste UI-prioriteit;
  • docentinzage geeft geen ouder-/voogdinzage;
  • ouder-/voogdinzage geeft geen docentinzage;
  • beheercontext verruimt geen gewone eindgebruikerscontext tenzij een expliciete beheer- of supportflow actief is.

De vaste UI-prioriteit voor gecombineerde frontpages is:

  1. Beheerder;
  2. Docent;
  3. Ouder/voogd;
  4. Leerling.

Omdat de leerlingrol niet combineerbaar is, verschijnt het leerlingblok alleen op een leerlingfrontpage. De prioriteit blijft wel vastgelegd voor fallback- en validatielogica.

Bij Docent + Ouder/voogd wordt één samengestelde frontpage getoond met docentblokken vóór ouder-/voogdblokken. Bij combinaties met Beheerder worden eerst de beheerderblokken getoond, daarna docentblokken en daarna ouder-/voogdblokken.

2.6 Publieke en niet-publieke rollen

Rollen kennen functioneel een onderscheid tussen publieke en niet-publieke rollen.

TypeBetekenis
Publieke rolMag binnen de toegestane registratie- of profielcontext door een gebruiker zelf gekozen of geactiveerd worden.
Niet-publieke rolMag uitsluitend via expliciete beheer-/adminflow worden toegekend of ingetrokken.

Niet-publieke rollen zijn minimaal:

  • Beheerder;
  • TestDocent;
  • toekomstige Admin-/autorisatiebeheerrol.

Een gebruiker mag niet via zelfregistratie, profielwijziging, clientstate, routeparameter, relatie-uitnodiging of oude sessiecontext een niet-publieke rol activeren.

Toekennen of intrekken van rollen moet altijd permissioncache-invalidatie veroorzaken voor de betrokken gebruiker. Beheer van rollen, permissions en rol-permissionkoppelingen zelf blijft buiten scope van Feature 11-5 en wordt voorbereid in Feature 17 story 091.

2.7 Permissions

Permissions zijn expliciete technische rechten die aan rollen worden gekoppeld via RolePermissions.

Naamgevingsconventie:

<resource>.<action>[.<scope>]

Voorbeelden:

PermissionBetekenis
frontpage.view.teacherDocentfrontpageblok mag zichtbaar zijn.
menu.view.guardian-childrenKinderenmenu voor ouder/voogd mag zichtbaar zijn.
student-results.read.ownEigen leerlingresultaten lezen.
student-results.read.assignedResultaten van toegewezen leerlingen lezen.
student-results.read.childrenResultaten van actief gekoppelde kinderen lezen.
teacher-levels.update.collaboratingEen niveau bewerken als collaborator.
administrator-system-settings.update.allSysteeminstellingen beheren binnen beheercontext.

Het volledige permissionregister staat in RBAC-permissieregister.

2.8 Permissioncheck versus domeincheck

Een permission opent een ingang, maar vervangt geen domein-/objectcontrole.

StapVraagVoorbeeld
PermissioncheckHeeft de gebruiker de vereiste permission?student-results.read.assigned
DomeincheckValt het concrete object binnen de toegestane context?Is deze leerling toegewezen aan deze docent en valt de run binnen een geautoriseerd niveau?

Voorbeelden:

  • student-results.read.assigned vereist daarna een docent-leerlingrelatie en niveauautorisatie;
  • student-results.read.children vereist daarna een actieve GuardianStudent-relatie;
  • teacher-levels.update.collaborating vereist daarna een actieve collaboratorstatus op het niveau;
  • practice-run.resume.own vereist daarna dat de run van de huidige leerling is en niet afgerond is;
  • administrator-teacher-support.update.all vereist daarna een expliciete supportflow en auditregistratie.

Domeinchecks blijven lokaal bij het domein dat de brondata bezit. Er komt geen centrale autorisatie-monoliet met alle leerling-, kind-, niveau-, ticket-, berichten- en runregels.

2.9 Relatiecontext

Relaties tussen accounts zijn zelfstandige autorisatiebouwstenen.

Een actieve relatie kan onder meer nodig zijn voor:

  • vriendschappen tussen leerlingen;
  • gedeelde oefeningen;
  • ouder-/voogdinzage;
  • ouder-/voogd-live-meekijken;
  • docent-leerlingtoegang;
  • docentresultaten binnen de eigen context;
  • docent-docentsamenwerking;
  • beheerder-beheerdercommunicatie.

Relaties worden vastgelegd per relatietype en context. Daardoor kan dezelfde natuurlijke persoon via verschillende niet-leerlingrollen verschillende relaties hebben met dezelfde leerling.

Voorbeelden:

  • iemand kan als Ouder/voogd een ouderrelatie met een leerling hebben;
  • dezelfde persoon kan als Docent ook een docent-leerlingrelatie met die leerling hebben;
  • deze twee relaties blijven functioneel gescheiden;
  • acties op de ene relatie mogen de andere relatie niet impliciet wijzigen.

2.10 Docentcontext

Docentfunctionaliteit werkt vanuit permissions en server-side docentcontext.

Een docent kan verschillende soorten toegang hebben:

ContextBetekenis
Eigenaar van niveauMag het niveau beheren en eigenaarschap onder voorwaarden overdragen.
Collaborator op niveauMag binnen dat niveau onderwijsinhoud bewerken, maar krijgt geen leerling-, resultaat- of live-meekijktoegang door collaboration alleen.
Docent-leerlingrelatieMaakt leerlinggerichte docentflows mogelijk, maar geeft niet automatisch toegang tot ieder niveau.
Niveauautorisatie voor leerlingBepaalt voor welke niveaus een leerling binnen docentcontext toegang heeft en waarover de docent resultaatinzage heeft.
Docent zonder geldige objectcontextKrijgt geen resultaat-, leerling- of live-inzage buiten de toegestane docentcontext.

Een docent ziet resultaten alleen wanneer zowel de permission als de eigen docentcontext geldig zijn. Directe URL’s, gemanipuleerde filters, oude bookmarks of gewijzigde autorisaties mogen geen resultaatdata buiten die context tonen.

2.11 Ouder-/voogdcontext

Ouder-/voogdfunctionaliteit gebruikt permissions plus de actieve GuardianStudent-relatie als domeincontrole.

Een ouder/voogd mag voor actief gekoppelde kinderen:

  • kinderenoverzicht raadplegen;
  • kindinformatie bekijken;
  • resultaten en geschiedenis over alle historische niveaus raadplegen;
  • resultaatdetails openen;
  • PDF-export starten;
  • online-status bekijken;
  • live meekijken wanneer een actieve oefenrun beschikbaar is.

Een ouder/voogd mag niet:

  • een oefening namens het kind starten;
  • een oefening hervatten;
  • antwoorden geven;
  • voortgang corrigeren;
  • resultaten wijzigen;
  • een oefening opnieuw maken namens het kind;
  • een oefening delen namens het kind.

Na ontkoppeling vervalt reguliere ouder-/voogdinzage direct voor nieuwe raadpleeg-, detail-, export- en liveacties. Historische runs blijven bestaan, maar worden niet gedeeltelijk getoond aan een gebruiker zonder actieve relatie.

2.12 Beheercontext en toekomstige Admin-context

Een beheerder heeft brede applicatiebeheermogelijkheden, maar beheercontext is geen vrije bypass op alle eindgebruikersfunctionaliteit.

Beheeracties zijn alleen toegestaan binnen expliciete beheer- of supportflows en vereisen passende beheerpermissions, zoals administrator-accounts.read.all, administrator-system-settings.update.all of tickets.resolve.all.

Een beheerder mag onder meer:

  • accounts beheren binnen de ondersteunde accountbeheerregels;
  • content beheren;
  • categorieën beheren en migreren;
  • modules beheren en migreren;
  • docentondersteuning uitvoeren;
  • meldingen behandelen;
  • beheerlogging en geschiedenis raadplegen.

Een beheerder mag niet automatisch:

  • rollen, permissions of rol-permissionkoppelingen beheren;
  • live meekijken in actieve leerlingruns;
  • reguliere leerlingoefeningen namens leerlingen uitvoeren;
  • ouder-/voogd- of docentcontext stilzwijgend overnemen buiten supportflows;
  • identity-providercredentials aanpassen;
  • wachtwoorden wijzigen;
  • autorisaties alleen via clientstate afdwingen.

Rollen- en permissionbeheer wordt apart voorbereid voor een toekomstige Admin-/autorisatiebeheerrol in Feature 17 story 091.

2.13 Accountstatus

Users.IsActive = false blokkeert reguliere OefenHub-toegang.

Dit betekent:

  • er wordt geen gewone frontpage opgebouwd;
  • permissioncache mag niet als toegangsbewijs worden gebruikt voor inactieve accounts;
  • bestaande historie wordt niet verwijderd;
  • relaties, berichten, meldingen, runs en auditdata blijven waar nodig historisch herleidbaar;
  • heractiveren vereist een expliciete beheerhandeling;
  • na heractiveren worden permissions, rollen, contexten en autorisaties opnieuw server-side bepaald.

Een gedeactiveerd of geanonimiseerd account mag niet via oude sessies, browsercontext, directe API-aanroepen of realtimeverbindingen alsnog beveiligde OefenHub-data raadplegen.

2.14 Permissioncache

Permissionchecks mogen niet bij iedere controle een databasequery veroorzaken.

Regels:

  • Bij login probeert OefenHub de effectieve permissions van de gebruiker te laden en 60 minuten te cachen, tenzij appsettings anders configureren.
  • De checkmethode kijkt altijd eerst in IMemoryCache.
  • Bij cache hit gebruikt de check de gecachete permission-set.
  • Bij cache miss haalt de check alle actieve permissions uit alle actieve rollen opnieuw op en zet deze opnieuw in de cache.
  • De cache is per gebruiker en bevat distinct permission-codes.
  • De cacheduur komt uit appsettings, bijvoorbeeld Authorization:PermissionCacheDurationMinutes.
  • IMemoryCache is voorlopig voldoende omdat er geen geplande multi-instance deployment is.
  • Bij toekomstige horizontale schaal moet dit worden vervangen of aangevuld met IDistributedCache of een gedeelde invalidatiestrategie.

Cache-invalidatie is verplicht bij:

  • publieke rolkeuze;
  • publieke rolwijziging via profiel;
  • toekennen of intrekken van een gebruikersrol;
  • deactiveren/heractiveren/anonimiseren van een account;
  • latere rol-permissionwijzigingen;
  • latere permissiondeactivatie;
  • expliciete beheer-/systemactie om de authcache van een gebruiker te legen.

2.15 Autorisatieprincipes

Voor alle rollen, permissions en contexten gelden de volgende autorisatieprincipes.

  • Autorisatie wordt server-side bepaald.
  • Iedere raadpleeg-, detail-, export-, mutatie- en liveactie herhaalt de relevante controle.
  • Een zichtbaar menu-item is geen autorisatiebewijs.
  • Een zichtbare knop is geen autorisatiebewijs.
  • Routeparameters zijn geen autorisatiebewijs.
  • Filters, paginering en zoektermen zijn geen autorisatiebron.
  • Browsergeschiedenis, bookmarks en oude selectiecontexten mogen toegang niet verruimen.
  • Clientstate mag presentatie versnellen, maar nooit rechten toekennen.
  • Bij ontbrekende toegang wordt geen gedeeltelijke gevoelige inhoud getoond.
  • Autorisatiefouten mogen geen kindnaam, runinhoud, antwoorddata, tokens, technische payloads of interne foutdetails lekken.
  • Lege toestanden zijn geen autorisatiefouten wanneer de gebruiker wel toegang heeft maar er geen data beschikbaar is.

2.16 Lege toestanden versus autorisatiefouten

Het FO maakt expliciet onderscheid tussen lege toestanden en autorisatiefouten.

SituatieBetekenis
Geen gekoppelde kinderenGeldige lege ouder-/voogdtoestand.
Geen afgeronde resultatenGeldige lege resultaten- of geschiedenisweergave.
Geen online kinderen of leerlingenGeldige lege onlineweergave.
Geen actieve oefeningen binnen categorieGeldige lege of verborgen oefenaanbodtoestand volgens zichtbaarheidregels.
Geen permission voor de ingangAutorisatiefout of veilige toegang-geweigerdafhandeling.
Geen toegang tot kind, leerling, run, niveau of beheerobjectAutorisatiefout of veilige toegang-geweigerdafhandeling.
Oude URL naar niet langer toegankelijke runAutorisatiefout; geen gedeeltelijke resultaatdata tonen.

Een lege toestand mag de gebruiker informeren. Een autorisatiefout moet veilig blokkeren.

2.17 Frontend, routes, guards en permission metadata

Frontendroutes, menu’s en knoppen mogen de gebruiker helpen navigeren, maar de backend blijft leidend.

OefenHub gebruikt declaratieve permission metadata, bijvoorbeeld:

  • endpointmetadata zoals RequirePermission("student-results.read.assigned");
  • componentmetadata zoals RequiresPermission("frontpage.view.teacher");
  • Blazor helpers zoals PermissionView of OefenHubPermissionGuard;
  • servicechecks via IOefenHubPermissionService.

ASP.NET RequireAuthorization() blijft bruikbaar voor baseline authenticatie. ASP.NET policies zijn optioneel implementatiedetail en niet de primaire functionele bron van OefenHub-autorisatie.

Routeguards mogen:

  • vroegtijdig navigatie blokkeren;
  • de gebruiker naar een veilige context sturen;
  • zichtbare menu-items verbergen;
  • fout- of toegangsschermen tonen.

Routeguards mogen niet:

  • server-side autorisatie vervangen;
  • oude clientstate vertrouwen;
  • routeparameters als bewijs gebruiken;
  • domeinregels overslaan;
  • gegevens tonen voordat server-side toegang is vastgesteld.

2.18 Audit en securitylogging

Niet iedere permissioncheck hoeft een zichtbare melding of auditregel op te leveren. Wel moeten relevante beheeracties, rolmutaties, permission-/rolepermission-mutaties, lifecyclewijzigingen, supportacties en gevoelige geweigerde toegangspogingen herleidbaar kunnen zijn.

Voorbeelden van auditwaardige acties:

  • niet-publieke rol toekennen of intrekken;
  • permission of rol-permissionkoppeling wijzigen;
  • permissioncache expliciet invalidaten door systeem of beheer;
  • account uitschakelen of heractiveren;
  • account anonimiseren;
  • docentondersteuning uitvoeren;
  • collaborator forceren;
  • eigenaarschap overdragen;
  • categorie- of modulemigratie uitvoeren;
  • beheerdermelding heropenen;
  • live-meekijksessie starten;
  • ouder-/voogdrelatie beëindigen.

Securitylogging bij geweigerde toegang mag geen gevoelige inhoud opslaan, zoals antwoorden, runpayloads, tokens of persoonsgegevens waarvoor de gebruiker geen toegang heeft.

2.19 Gerelateerde bronverwijzingen

BronLink
Ontwerpbron — RBAC-permissieregisterRBAC-permissieregister
Ontwerpbron — autorisatiematrixAutorisatiematrix
Technisch Ontwerp — identiteit en rolcontextIdentiteit, authenticatie en rolcontext
Technisch Ontwerp — autorisatieAutorisatie, policies en server-side contextcontrole
Technisch Ontwerp — rolflowsRollenflows technisch
Database-informatie — identiteit en autorisatieIdentiteit en autorisatie
Database-informatie — relatiebeheerRelatiebeheer
Database-informatie — docentstructuur en leerlingtoegangDocentstructuur en leerlingtoegang
FO — account, profiel en voorkeurenAccount, profiel en voorkeuren
FO — relatiebeheerRelatiebeheer
FO — live meekijkenLive meekijken