MBO-SD : De site voor software developer in het MBO
Rollen en rechten
De gebruiker is een User entity
Als je inlogd in het systeem is de gebruiker User entity.
Veld roles in de database
Als je de stappen hebt doorlopen zoals hier beschreven heeft een gebruiker standaard in de database een
veld genaamd roles
. Die heeft standaard de waarde van een lege array []
Je kan deze ophalen door de ->getRoles()
methode aan te roepen. Deze zal dan de array teruggeven
met, in de basis, altijd een rol ROLE_USER
Standaard ROLE_USER
Bij de standaard installatie zoals we deze in de eerdere paragrafen hebben doorlopen heeft de gebruiker
standaard altijd een ROLE_USER
rol. Dit komt door het volgende stukje code in de
src/Entity/User.php
public function getRoles(): array
{
$roles = $this->roles;
// guarantee every user at least has ROLE_USER
$roles[] = 'ROLE_USER';
return array_unique($roles);
}
Andere mogelijke rollen?
Je kan zelf naar hartelust rollen verzinnen in een systeem. Denk bijvoorbeeld aan een ziekenhuis, daar heb je diverse rollen:
- Doktoren (ROLE_DOCTOR)
- Patienten (ROLE_PATIENT)
- Beheerders (ROLE_ADMIN)
- Assistenten (ROLE_ASSISTANT)
- Afdelingshoofd (ROLE_DEPARTMENTHEAD)
- Gasten (zij hebben geen rol, want zijn niet ingelogd)
En zo kunnen we nog wel even door gaan. In het systeem van Symfony kan een gebruiker ook meerdere rollen hebben.
Iedereen die ingelogd is heeft sowieso de rol ROLE_USER
vanuit bovenstaande code en daar kan dus een
andere rol bijkomen. Uiteraard in een goede omgeving heb je als beheerder een pagina om de gebruikers van het
systeem de mogelijkheid om een gebruiker een of meerdere rollen te geven.
Denk bijvoorbeeld aan een dokter. Deze heeft standaard al de rol ROLE_USER
en zal ook de rol
ROLE_DOCTOR
krijgen waarmee hij in het systeem patienten kan inzien en diagnoses kan opschrijven.
In de database kan je in het veld dan de volgende code zetten in het veld van deze gebruiker:
["ROLE_DOCTOR"]
. De gebruiker in het systeem heeft nu de rollen ROLE_USER
en
ROLE_DOCTOR
Stel dat deze dokter de hoofd van een afdeling wordt dan krijgt hij een derde rol, namelijk die van
ROLE_DEPARTMENTHEAD
. In de database kan je het veld van deze gebruiker dan veranderen door deze
rol toe te voegen, het nieuwe veld heeft dan als waarde: ["ROLE_DOCTOR", "ROLE_DEPARTMENTHEAD"]
De gebruiker heeft beide rollen nodig, hij is immers nog dokter in het ziekenhuis en moet bij de patienten
gegevens kunnen, maar als afdelingshoofd moet hij ook bij de personeelsbestanden kunnen.
Werken met rollen in Controler
In een controller heb je de functie $this->isGranted("ROLE")
met deze ingebouwde functie kan je snel kijken of er een gebruiker is ingelogd en als dit zo is
of de gebruiker de betreffende rol heeft. Als de gebruiker de rol niet heeft, of niet ingelogd is, geeft
deze functie FALSE
terug, heeft de gebruiker de betreffende rol, dan krijg je TRUE
.
Deze kan je op deze wijze in een controller gebruiken met een if
statement.
#[Route('/', name: 'app_index')]
public function index(): Response
{
if ($this->isGranted("ROLE_ADMIN") {
//The user has the role ROLE_ADMIN
} else {
//User is no admin
}
}
Checken van user en rechten in TWIG-bestanden
In de TWIG bestanden heb je de functie is_granted("ROLE")
. Op dezelfde wijze als in de
Controller met $this->isGranted()
kan je de is_granted("ROLE")
ook in TWIG
bestanden gebruiken.
<div class="row">
{% if is_granted("ROLE_ADMIN") %}
- Je bent een beheerder van ons systeem
{% endif %}
</div>
Afschermen van routes
In een goede veilige applicatie werk je met routes op basis van logica, de routes passen bij hetgene wat je
wilt doen. Een route kan uit een of meerdere slugs
bestaan. (http://localhost:8000/patients/show/1
heeft 3 slug-onderdelen, patients
, show
en 1
.
Om er voor te zorgen dat een dokter wel bij de informatie van alle patienten kan en een patient alleen zijn eigen profiel
kan zien (/profile/show
) kan je de hele slug van /patients/
beveiligen dat alleen de
rollen van doktoren, assistenten erbij kunnen.
De security.yaml
Dit afschermen doe je in het bestand /config/packages/security.yaml
. Als je dit bestand opent
dan heb je op een gegeven moment een deel dat begint met access_control
//..
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
# - { path: ^/admin, roles: ROLE_ADMIN}
# - { path: ^/profile, roles: ROLE_USER }
Als je de #
weg zou halen heb je twee beschermde onderdelen in de applicatie. /admin/
en alles wat er na komt. Dit is alleen toegankelijk voor gebruikers met de rol ROLE_ADMIN
En een
/profile/
onderdeel wat alleen toegankelijk is voor ingelogde gebruikers. (Alle gebruikers die
ingelogd zijn hebben immers de rol ROLE_USER
Meerdere rollen op een onderdeel
Heb je een onderdeel wat, zoals in bovenstaand voorbeeld, voor meerdere rollen toegankelijk is, dan kan je van de naam ook een array maken:- { path: ^/patients, roles: [ROLE_DOCTOR, ROLE_ASSISTANT] }
Afschermen van een functie/ method in een controller
Naast dat je hele stukken code kan afschermen kan je ook in een Controller
een functie afschermen.
Dit kan je doen door boven de #[ROUTE ..]
een extra beveiligingsregel te
plaatsen #[IsGranted('ROLE_USER')]
//In de use-space staat ook de volgende zin:
use Symfony\Component\Security\Http\Attribute\IsGranted;
//Verder op in de code
#[IsGranted('ROLE_USER')]
#[Route('/home', name: 'app_home')]
public function home() :Response
{
return $this->render('home/index.html.twig');
}
Bovenstaande code geeft alleen toegang tot ingelogde gebruikers. Als een gebruiker niet ingelogd is zal het systeem vragen om in te loggen, als een gebruiker geen toegang heeft komt er een access denied melding.
Er zijn meer mogelijkheden
Er zijn meer mogelijkheden om de toegang te controleren in de Controller, dit is de basis maar online als je zou zoeken kan je dus nog andere oplossingen tegenkomen.