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

Testing SAML needs a real identity provider—there is no offline mode and no mock. KeyCloak in DDEV is the shortest way to one, and the repository includes an example realm so you do not have to click a SAML client together by hand.

Setup

Install the KeyCloak add-on and restart:

ddev add-on get b13/ddev-keycloak && ddev restart

Import the example realm. The two JSON files are development fixtures in this repository (Resources/Private/Examples/sso-example-*.json); they are not part of the Composer package. Copy them from a checkout:

cp /path/to/sso-authentication/Resources/Private/Examples/sso-example-*.json \
   .ddev/keycloak/import/
ddev kcctl import

Point the backend at the matching service provider configuration:

$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['sso_authentication']['BackendServiceProviderConfigurationFile']
    = 'EXT:sso_authentication/Resources/Private/Examples/sso_authentication.yaml';

Then open the backend login screen and pick the SSO entry. The example user is benni-example with the password huhu2025.

This is a local-development shortcut, not a template for production. The SAML client does not require a client signature, and pointing the backend at the example inside the extension means the next composer update replaces your configuration. Copy sso_authentication.yaml into your own site package for anything else.

The realm export carries no keys. KeyCloak generates its own signing keys on import when the file does not include them. If you export a realm of your own to share, strip components."org.keycloak.keys.KeyProvider" before you commit it.

What the Example Realm Contains

Piece Value
Realm sso-example
SAML client ${DDEV_PROJECT}.ddev.site/typo3/—the DDEV project name is substituted on import, so the same file works in any project
Name identifier The KeyCloak username
Client signature Not required, so TYPO3 does not have to sign its requests for this realm
Group Erste Gruppe, which benni-example is a member of
Attribute mappers urn:oid:1.2.840.113549.1.9.1 (email), urn:oid:2.5.4.42 (given name), urn:oid:2.5.4.4 (surname), and a group-membership mapper under the attribute name bennis-group-list

Those four attribute names are exactly the keys the shipped sso_authentication.yaml maps, which is why the pair works out of the box. Note what the realm does not send: no tenant and no object identifier claim. So tx_sso_tenantid stays empty and tx_sso_objectidentifier falls back to the name identifier—the same situation as a typical KeyCloak setup in production, and the reason the mapped email matters for matching an existing user.

Setting a Realm Up by Hand

If you would rather build it yourself, or need a second realm:

  1. Admin console at your-project.ddev.site/admin, with admin / password
  2. Create a realm—Master > Create realm
  3. Create a user—Users > Add user, give them a password on the Credentials tab with Temporary off, and add them to a group under Users > user > Groups
  4. Create a SAML client—Clients > Create client, type SAML:
  5. Attribute mappers—Client Scopes > add predefined mapper. Skip the role list mapper
  6. Group mapper—Add Mapper > By Configuration > Group list. The Group attribute name is what your claimsMapping key has to be

Export before you commit anything you changed in the admin console, or the next import overwrites it:

ddev kcctl export
ddev kcctl import

Troubleshooting

Check the environment variables first—a %env(...)% placeholder that resolves to an empty string produces an unhelpful failure a long way from its cause. Then switch on debug logging and request the metadata endpoint; between the two, nearly every local problem is visible.

For KeyCloak’s own side, add this to .ddev/docker-compose.keycloak.yaml, restart, and follow the log with ddev logs -s keycloak -f:

environment:
  - KEYCLOAK_LOG_LEVEL=DEBUG

Common Issues

Symptom Cause
client_not_found, or Cannot_match_source_hash The client ID in KeyCloak does not match the entity ID TYPO3 sends. Almost always the trailing slash
Found an Attribute element with duplicated Name Two mappers in the client scopes produce the same attribute name. Remove one, or set security.allowRepeatAttributeName if you cannot
The login form comes back with nothing on screen The normal symptom of every rejected assertion. Logging has the reason. Over https through a proxy, start at Reverse Proxy
A new be_users row appears on every login userStoragePid is not 0 for the backend, or nothing in the claims matches the existing user. See User Federation

Mapping an Attribute You Can See in KeyCloak

The keys of claimsMapping are the SAML Attribute Name shown under Clients > your client > Client scopes, and the values are column names of be_users or fe_users. There is no discovery step: an attribute the identity provider sends and the mapping does not name is simply ignored, which is why an attribute arriving correctly and still not landing in the record is the most common mapping mistake. Debug logging prints both the raw claims and the mapped result of every login, which is the fastest way to see which of the two is missing.