Files
ephub/config/packages/security.yaml
T
2026-10-05 17:10:02 +02:00

64 lines
3.4 KiB
YAML

security:
# Symfony's default, stated because it is a decision: the session id is regenerated on a
# successful login, so a session id an attacker planted beforehand is not the one that ends
# up authenticated.
session_fixation_strategy: migrate
# No password_hashers: there are no passwords here. Authentication is OAuth2 against myep,
# which owns the credentials; ephub only ever sees a userinfo response.
# An administrator can do everything a supervisor can, so the "may act on other people's
# bookings" checks ask for ROLE_SUPERVISOR alone. Only isGranted() sees this:
# User::getRoles() still returns the stored roles, which is why CodeVisibility names
# ROLE_ADMIN explicitly.
role_hierarchy:
ROLE_ADMIN: [ROLE_SUPERVISOR]
providers:
app_user_provider:
entity:
class: App\Entity\User
property: email
firewalls:
dev:
# _error is the dev-only preview of the error pages (/_error/404, /_error/500).
pattern: ^/(_profiler|_wdt|_error|assets)/
security: false
main:
lazy: true
provider: app_user_provider
entry_point: App\Security\LoginEntryPoint
custom_authenticators:
- App\Security\EpAuthenticator
# The local lockout. Roles follow myep on every login and a deleted row is simply
# provisioned again, so this flag is the only thing here that myep cannot undo.
user_checker: App\Security\UserChecker
logout:
path: app_logout
target: app_login
# Without this any third-party page can log somebody out by embedding the URL.
# The header link is a form POST for the same reason.
enable_csrf: true
# Local only: there is no RP-initiated logout against myep and no token
# revocation, so this ends the ephub session and nothing else. It matters less
# than it usually would -- myep destroys its own session immediately after an
# external authorization request, so there is normally no SSO session left to
# end -- and the access token is gone either way, never having been stored.
access_control:
# The login surface itself has to stay reachable, or the entry point redirects in a loop.
- { path: ^/(login|auth|logout)$, roles: PUBLIC_ACCESS, requires_channel: https }
- { path: ^/auth/, roles: PUBLIC_ACCESS, requires_channel: https }
# Before the catch-all, or ROLE_EMPLOYEE would match ^/ first and the admin area would be
# open to everybody. Order is the whole guard here.
- { path: ^/admin, roles: ROLE_ADMIN, requires_channel: https }
# Everybody's bookings, for supervisors and (through role_hierarchy) administrators. Kept
# out of ^/admin so that everything under it stays administrator-only.
- { path: ^/manage, roles: ROLE_SUPERVISOR, requires_channel: https }
# Any of these opens the app -- access_control treats a list of roles as an OR. Not
# ROLE_USER: myep authenticates far more people than work here, and someone who holds
# none of these is refused at login with an explanation rather than let in to an empty
# screen. Keep in step with Role::ELIGIBLE.
- { path: ^/, roles: [ROLE_EMPLOYEE, ROLE_SUPERVISOR, ROLE_ADMIN], requires_channel: https }