---
title: Events
url: "https://b13.com/products/single-sign-on-for-typo3/documentation/events"
date: 2026-09-10
modified: 2026-11-10
---

# Events

![Icon featuring a key and overlapping squares, symbolizing security or access control.](https://b13.com/fileadmin/_processed_/0/a/csm_sharing-ext-SingleSignOn-S_512e772865.webp)

  Documentation
===============

 TYPO3 Module “Single-Sign-On”
 Version 2.0.3 (04 Nov 2026)

   Chapters of this Documentation        Two PSR-14 events sit in the path of every SSO login. One fires before a user is created, the other before an existing user's data is refreshed. Both hand you the data about to be written and the claims it came from.

Register a listener the usual way, in your extension's `Configuration/Services.yaml`:

     Copy

```
```
services:
  MyVendor\MyExt\Sso\RestrictFederation:
    tags:
      - name: event.listener
        identifier: 'my-ext/restrict-federation'
```
```

   BeforeUserCreationEvent
-------------------------

`B13\SSOAuthentication\Event\BeforeUserCreationEvent`

Dispatched immediately before the insert, only when [federation](https://b13.com/products/single-sign-on-for-typo3/documentation/user-federation) is enabled and no existing user was found.

| Method | Returns |  |
|---|---|---|
| `getUserData()` | `array` | The record about to be inserted: the mapped claims plus `username`, `pid`, `usergroup`, `crdate` and `tx_sso_sessionindex` |
| `setUserData(array $userData)` | `void` | Replaces it |
| `getUserClaims()` | `SsoUserDetails` | The claims from the assertion, mapped and raw |
| `getSamlSettings()` | `SamlSettings` | The resolved settings for this scope |
| `loginType` | `?string` | Readonly property, `'BE'` or `'FE'` |
| `preventCreation()` | `void` | Cancels the insert |

**`preventCreation()` is new in 2.0.0.** The event implements `StoppableEventInterface`, and calling it stops propagation—so no listener registered after yours runs either. The login is then treated exactly as if federation had been switched off: no user is created, the login is refused, and the refusal is recorded at `info` level.

This is how you keep an identity provider that also serves other applications from handing out TYPO3 accounts to everybody it authenticates:

     Copy

```
```
final class RestrictFederation
{
    public function __invoke(BeforeUserCreationEvent $event): void
    {
        if ($event->loginType !== 'BE') {
            return;
        }
        $department = $event->getUserClaims()->getClaim('department');
        if ($department !== 'Editorial') {
            $event->preventCreation();
        }
    }
}
```
```

  Note the `loginType` guard. Both scopes dispatch the same event, and a listener without that check applies to frontend users too.

The extension registers a listener of its own on this event, which gives a federated **backend** user `options = 3` and, with EXT:workspaces installed, live-workspace permission. Calling `preventCreation()` from your own listener stops propagation, which may stop that one from running—harmless here, since nothing is created anyway.

   BeforeUserDataUpdatedEvent
----------------------------

`B13\SSOAuthentication\Event\BeforeUserDataUpdatedEvent`

Dispatched before the update that runs on **every** successful login, for federated and hand-made users alike.

| Method | Returns |  |
|---|---|---|
| `getUpdateData()` | `array` | The columns about to be written |
| `setUpdateData(array $updateData)` | `void` | Replaces them |
| `getUserData()` | `array` | The user record as it currently stands in the database |
| `getUserClaims()` | `SsoUserDetails` | The claims from the assertion |
| `loginType` | `?string` | Readonly property, `'BE'` or `'FE'` |

Removing a key is how you stop SSO from overwriting a value somebody corrected by hand:

     Copy

```
```
final class KeepManualRealName
{
    public function __invoke(BeforeUserDataUpdatedEvent $event): void
    {
        $data = $event->getUpdateData();
        unset($data['realName']);
        $event->setUpdateData($data);
    }
}
```
```

  `tx_sso_sessionindex` is added to the data *after* this event, so it cannot be removed. A [single logout](https://b13.com/products/single-sign-on-for-typo3/documentation/how-it-works#c12359) needs it, and a login that quietly skipped it would leave a session nobody can end.

  ###  Why This One Cannot Be Stopped

There is no `preventUpdate()`, and the event does not implement `StoppableEventInterface`. That is deliberate: at this point the user has already been authenticated and the login **will** succeed. An event that could cancel the update would not cancel the login—it would only produce a session whose user record no longer matches the assertion it was created from, with a stale `tx_sso_sessionindex` and stale group membership.

If you want to refuse somebody, refuse the creation with `preventCreation()` above, or disable the user record. If you want to keep a column, remove that column from the update data. Those two cover the cases a veto would be reached for, without the half-applied state.