Skip directly to page content
b13 GmbH

Hauptstätter Str. 59
70178 Stuttgart
Germany
+49 (0) 711 460 589 70 [email protected]
Icon featuring a key and overlapping squares, symbolizing security or access control.

Documentation

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

Chapters of this Documentation

1. Install the Package

composer require b13/sso-authentication

2. Create the Table Columns

vendor/bin/typo3 extension:setup --extension=sso_authentication

This adds four columns to be_users and fe_users. Without them no login can be recorded and every SSO login fails on the database write—see the tx_sso_* columns for what each one holds. Any other schema update works too, including the Install Tool’s "Analyze Database Structure".

3. Generate a Certificate and Key

The identity provider needs a public certificate to verify the requests TYPO3 signs, and to encrypt what it sends back. Keep both files outside the docroot:

mkdir -p var/private var/certs
openssl req -x509 -sha256 -nodes -days 730 -newkey rsa:4096 \
    -keyout var/private/saml.key \
    -out var/certs/saml.crt

Signing is not switched on by the certificate alone—the security keys decide that, see Configuration. A setup without signed requests works, and some identity providers require you to turn signature checking off on their side before it does.

Note the expiry date. A certificate the identity provider has pinned stops logins on the day it runs out, with a rejected assertion and nothing on screen. Two years is the default above; put the date somewhere you will see it.

4. Configure Environment Variables

The configuration file resolves %env(...)% placeholders, so the paths and the metadata URL stay out of the versioned file:

SSO_METADATAURL="https://idp.example.com/saml/metadata"
SSO_CERTIFICATE="var/certs/saml.crt"
SSO_PRIVATEKEY="var/private/saml.key"

SSO_CERTIFICATE and SSO_PRIVATEKEY may hold an absolute path, a path relative to the project root, or the PEM content itself. Placeholder resolution only happens for YAML files—an XML configuration file is read verbatim.

5. Extension Settings

Settings → Extension Configuration → sso_authentication, or in PHP:

$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['sso_authentication']['<setting>'] = '<value>';
Setting Default Purpose
enableBE 1 Registers the authentication service and the SSO entry on the backend login screen. Also makes the be_users password field optional, so a user without a password can exist
enableFE 1 The same for the frontend: the authentication service and an optional fe_users password
BackendServiceProviderConfigurationFile (empty) Path to the backend service provider configuration file. Empty means backend SSO does nothing at all, even with enableBE on
BackendBaseUrl (empty) Prefix applied when entityId resolves to a value with no scheme. Has no effect otherwise—see BackendBaseUrl

Both switches default to on, so the decision you actually make here is which configuration source you fill in.

Backend—point the extension at a configuration file. Use EXT: syntax or a full URL; a plain project-relative path is treated as a URL and fails:

The extension configuration of sso_authentication: "Enable SSO for backend" and "Enable SSO for frontend" both ticked, the path to the backend service provider configuration file set to EXT:sso_demo/Configuration/Sso/backend.yaml, and the base URL for the service provider metadata left empty.
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['sso_authentication']['BackendServiceProviderConfigurationFile']
    = 'EXT:my_site_package/Configuration/Sso/backend.yaml';

Copy EXT:sso_authentication/Resources/Private/Examples/sso_authentication_example.yaml into your own site package as a starting point. Do not reference the shipped example from a production installation—it is overwritten on every update.

Frontend—per site, in the site configuration. enabled and metadata are both required; without either, frontend SSO stays off for that site:

settings:
  sso_authentication:
    enabled: true
    metadata: 'EXT:my_site_package/Configuration/Sso/frontend.yaml'
    userStoragePid: 42

The full set of keys for both scopes is in Configuration.

6. Register TYPO3 at the Identity Provider

Every endpoint is derived from a base URL: the backend entry point for backend logins, the site base URL for frontend logins. Backend and frontend are separate service providers with their own entity IDs, so an installation using both is registered twice—and a multi-site installation once per site.

If your identity provider can consume service provider metadata, point it at the metadata endpoint instead of typing URLs in by hand.

Backend Endpoints

Base URL is the backend entry point, example.com/typo3/ by default. It follows $GLOBALS['TYPO3_CONF_VARS']['BE']['entryPoint'] and is resolved from the request, so a custom backend path and a subdirectory installation are both covered without configuration.

Endpoint URL Configured Via
Entity ID example.com/typo3/ (mind the trailing slash) entityId, defaults to the entry point
Assertion consumer service example.com/typo3/auth/sso/acs acsUrl, defaults to the entry point plus auth/sso/acs
Service provider metadata example.com/typo3/auth/sso/metadata metadata.url, no default
Single logout example.com/typo3/ not configurable

The single logout URL appears in the metadata but has no backend handler. Logging out of the backend ends the TYPO3 session locally without notifying the identity provider; single logout is implemented for the frontend only, see How It Works.

Frontend Endpoints

Base URL is the base of the site as defined in the site configuration.

Endpoint URL Configured Via
Entity ID example.com entityId, defaults to the site base
Assertion consumer service example.com/_auth/sso/acs acsUrl, defaults to /_auth/sso/acs
Service provider metadata whatever metadataUrl says metadataUrl, no default—the endpoint is off until you set it
Single logout example.com not configurable

The assertion consumer service works out of the box; the metadata endpoint does not. Note that metadataUrl is matched against the request path exactly, so a trailing slash or a sub-path does not match—unlike the backend, which matches metadata.url as a substring of the path.

Production Checklist

  1. Certificate and key resolve. Check the metadata endpoint: a missing key shows up as an empty KeyDescriptor rather than an error
  2. The configuration source is actually set. For the backend that is BackendServiceProviderConfigurationFile; an empty value disables SSO silently. For the frontend it is enabled and metadata per site
  3. userStoragePid is 0 for the backend. Anything else creates backend users TYPO3 will not find on the next login, and federation then creates another one. For the frontend, point it at your fe_users folder. See userStoragePid
  4. Every scope and every site is registered at the identity provider. Entity ID and assertion consumer service are per service provider, and a multi-site installation has one set per site
  5. Behind a TLS-terminating proxy, reverseProxyIP and reverseProxySSL are set. Without them every assertion is rejected for a Destination mismatch, and the only symptom is the login form coming back. See Reverse Proxy
  6. You know how you get back in if the identity provider fails. With enforceSSO on there is no password form left. The Install Tool has its own authentication and remains reachable—see Losing the Identity Provider
  7. Frontend enforceSSO has a loginFormPage. It is the one page that stays reachable while logged out; without it every frontend URL bounces to the identity provider
  8. federation.enabled is a deliberate decision. On, every identity the provider authenticates gets a TYPO3 account. Off, an unknown identity is rejected. See User Federation
  9. The log level is not left at debug. Debug logging writes the complete attribute set of every successful login—personal data—into an unrotated file. See Logging

Smoke Test

Does the configuration resolve? Request the metadata endpoint. Valid XML means the file was found, the certificate was read, and the SAML toolkit accepted the settings. An error page means it did not: the message names the rejected setting:

curl -sS https://example.com/typo3/auth/sso/metadata | head -20

Compare the entityID attribute and the AssertionConsumerService location in the output against what the identity provider has registered. A mismatch here is the cause of most rejected assertions. Below, the frontend client of the KeyCloak demo realm and the frontend metadata; for the backend, compare the same two values from the backend metadata endpoint.

Does a login work? Open the backend login screen, pick the SSO entry, and sign in at the identity provider. On success you land in the backend module menu. On failure you land back on the login form with nothing on screen—the reason is in the Log module (Administration > Log, in v13 System > Log), see Logging.

The KeyCloak client of the demo realm next to the service provider metadata TYPO3 publishes. The client ID "https://sso-demo.b13.example/typo3-frontend" is identical to the entityID in the metadata, and the assertion consumer service location "https://sso-authentication.ddev.site/_auth/sso/acs" is covered by the valid redirect URI "https://sso-authentication.ddev.site/*". A difference in either pair is the most common reason an assertion is rejected.