AxiamAuthSubscriber
in package
implements
EventSubscriberInterface
Symfony authentication subscriber (D-02, CONTRACT.md §10): listens to `kernel.request`, extracts the bearer/cookie token, verifies it via {@see AxiamClient::verifyLocallyOrFallback()} — local JWKS verification first, falling back to the shared single-flight refresh (§9, D-06) — and populates the `axiam_user` request attribute with `user_id`/`tenant_id`/`roles` on success.
Short-circuits the request with a standardized 401 JSON error body on any failure (missing token, invalid signature, expired-and-unrefreshable token). Never duplicates JWKS-verify or refresh logic itself (D-02 prohibition) — every security-critical decision is made by AxiamClient.
MUST be manually registered (Pitfall 5): Symfony has no Laravel-style zero-config
auto-discovery for a plain composer require without a published Flex recipe (out
of scope this phase). A consuming app must tag this class
kernel.event_subscriber in its own config/services.yaml in addition to listing
AxiamBundle in config/bundles.php — see examples/symfony_app/.
CSRF (cookie double-submit, CONTRACT.md §3): when the credential was sourced from
the axiam_access COOKIE (not the Authorization header) and the request method
is state-changing (anything other than GET/HEAD/OPTIONS), this subscriber
additionally requires the X-CSRF-Token request header to be present and equal
(constant-time) to the axiam_csrf cookie value, short-circuiting with 403 on
mismatch/absence. Bearer-header requests are CSRF-immune by construction — a
cross-site attacker cannot set arbitrary request headers — but a cookie
automatically attached by the browser is not, and in any same-site deployment
where axiam_access reaches this app, the non-httpOnly axiam_csrf cookie does
too. This mirrors, locally, the same double-submit check the AXIAM server performs
on its own endpoints (§3).
Table of Contents
Interfaces
- EventSubscriberInterface
Methods
- __construct() : mixed
- getSubscribedEvents() : array<string, string>
- onKernelRequest() : void
- Authenticates the inbound request and, for cookie-authenticated writes, enforces CSRF.
Methods
__construct()
public
__construct(AxiamClient $client, string $tenant) : mixed
Parameters
- $client : AxiamClient
- $tenant : string
getSubscribedEvents()
public
static getSubscribedEvents() : array<string, string>
Return values
array<string, string>onKernelRequest()
Authenticates the inbound request and, for cookie-authenticated writes, enforces CSRF.
public
onKernelRequest(RequestEvent $event) : void
Sequence: extract the credential (Authorization: Bearer first, then the
axiam_access cookie) → verify the JWT locally against the cached JWKS → enforce the
cross-tenant claim check → inject the identity onto the request.
CSRF (CONTRACT.md §3a): when the credential came from the COOKIE and the method is
state-changing (not GET/HEAD/OPTIONS), the X-CSRF-Token header must be present and
equal (constant-time) to the axiam_csrf cookie, else a 403 response is set on the
event. Bearer-authenticated requests are exempt — a cross-site attacker cannot set
custom request headers.
Parameters
- $event : RequestEvent
-
Kernel request event; a 401/403 JSON response is set on it to short-circuit the request on failure.