---
title: How It Works
url: "https://b13.com/products/single-sign-on-for-typo3/documentation/how-it-works"
date: 2026-09-10
modified: 2026-11-10
---

# How It Works

![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        TYPO3 is the service provider. It never sees a password: it sends an authentication request to the identity provider, and the identity provider sends back a signed assertion naming the user. Everything below is that exchange, plus what TYPO3 does with the result.

   The Pieces
------------

| Class | Role |
|---|---|
| `SsoAuthentication` | The authentication service. Validates the assertion, resolves the TYPO3 user, decides whether the login is accepted. Registered at priority 80—above the username/password service at 50 |
| `SsoLoginProvider` | The backend login screen entry, and the redirect to the identity provider |
| `BackendSsoReceiver` | Backend middleware. Serves the metadata endpoint and turns an incoming assertion into something core's authentication recognizes |
| `FrontendSsoReceiver` | The same for the frontend, plus the redirect to the identity provider |
| `FrontendRedirectToIdp` | Frontend middleware running after authentication. Handles enforcement, logout, and the no-groups case |
| `ProvideRequestTokenProvider` | Supplies the request token core expects from a login form, which an SSO login has no form to get it from |

    ![A frontend login with SSO: the visitor on the login form page clicks the SSO link built from ssoAcsRedirectUrl, which is a GET to /_auth/sso/acs?logintype=sso. FrontendSsoReceiver builds the authentication request, with RelayState set to redirect_url if given, else the language base, and answers with a 307 redirect to the identity provider, where the user authenticates. The identity provider posts SAMLResponse and RelayState back to /_auth/sso/acs. FrontendSsoReceiver sets logintype=login and username=_SSO_, a signed pid holding userStoragePid, the sanitized RelayState as referer, and rewrites the routing attribute to loginFormPage. In the typo3/cms-frontend/authentication middleware, SsoAuthentication::processLoginData() validates the assertion, SsoAuthentication::getUser() resolves or creates the user, and SsoAuthentication::authUser() returns 200. FrontendRedirectToIdp then sees a logged-in request, and the visitor is redirected to the RelayState target, or to the site base.](https://b13.com/fileadmin/products/docs/sso-authentication/Documentation-Images-frontend-login-flow.svg)

 A Frontend Login
------------------

The routing rewrite in the middle is not cosmetic. The assertion arrives at the assertion consumer service path, which is not a TYPO3 page—left alone, TYPO3 would answer the request that carries the successful login with a 404. The middleware makes routing resolve `loginFormPage` (or the site root) instead.

The `pid` handed to core carries an HMAC alongside the value, which is how `FrontendUserAuthentication` accepts a storage folder restriction it did not receive from a form.

    ![A backend login with SSO: on the backend login screen SSO appears in the provider switch. When it is clicked, or immediately when enforceSSO is on, SsoLoginProvider::modifyView() answers with a 307 redirect to the identity provider, where the user authenticates. The identity provider posts the assertion to /typo3/auth/sso/acs, a public backend route. BackendSsoReceiver sets login_status=login and username=_SSO_. In the typo3/cms-backend/authentication middleware the same three steps as in the frontend login follow: SsoAuthentication::processLoginData() validates the assertion, SsoAuthentication::getUser() resolves or creates the user, and SsoAuthentication::authUser() returns 200. The backend renders.](https://b13.com/fileadmin/products/docs/sso-authentication/Documentation-Images-backend-login-flow.svg)

 A Backend Login
-----------------

The assertion consumer service is a registered backend route with `access: public`, so an unauthenticated POST reaches it. Its target is core's own `BackendController::mainAction`, which means the request that delivers the assertion is also the request that renders the backend—no intermediate redirect, and no chance of losing the POST body on the way.

The metadata endpoint needs no route. `BackendSsoReceiver` runs before backend routing and answers it directly.

   What Happens to the User Record
---------------------------------

On every successful login, whether the user was found or just created:

- The mapped claims are written to the user record
- `tx_sso_objectidentifier` is set from the object identifier claim, falling back to the name identifier when the identity provider sends none
- `tx_sso_tenantid` is set when a tenant claim is present
- `tx_sso_sessionindex` is set from the assertion’s session index, which is what a later single logout request needs
- Group membership is reconciled when a claim maps to `usergroup`

The details, including which groups survive, are in [User Federation](https://b13.com/products/single-sign-on-for-typo3/documentation/user-federation#c12397). A listener can change what is written, see [Events](https://b13.com/products/single-sign-on-for-typo3/documentation/events).

   ?logintype=sso
----------------

Starts a frontend login. It is only acted on at the assertion consumer service URL, with a GET—`/_auth/sso/acs?logintype=sso` by default. Anywhere else the parameter is ignored.

This is the URL `ModifyFrontendLoginView` hands your template as `ssoAcsRedirectUrl`, ready-made. It is also where the enforced redirect sends an anonymous visitor. See [Frontend Login](https://b13.com/products/single-sign-on-for-typo3/documentation/frontend-login).

   Single Logout
---------------

`?logintype=slo` is the frontend logout, and it covers three different situations. All of them are handled in `FrontendRedirectToIdp`, which runs after authentication and therefore knows whether anybody is logged in.

**Service-provider-initiated—the visitor logs out of TYPO3.** A logged-in request carrying `?logintype=slo` produces a logout request built from the user's `tx_sso_sessionindex` and their username as the name identifier, and the visitor is redirected to the identity provider to end the session there too. The TYPO3 session is still alive at this point.

**Identity-provider-initiated—or the response to the above.** A request carrying `SAMLResponse` or `SAMLRequest` **in the query string** while logged in is processed as single logout: the TYPO3 frontend session is ended, and the visitor is redirected to whatever the toolkit returns, or to the site base. This is also the branch that closes out the service-provider-initiated case, because the identity provider sends its logout response back to the single logout endpoint—the site base with `?logintype=slo`.

**Already logged out.** `?logintype=slo` on the site base or the assertion consumer service URL without a session redirects to `loginStatusPage`.

**The backend has no equivalent.** The single logout URL is generated into the backend metadata, but no middleware handles it. Logging out of the backend ends the TYPO3 session and nothing else—the identity provider still considers the user signed in, so the next backend login goes through without a prompt.