---
title: Frontend Login
url: "https://b13.com/products/single-sign-on-for-typo3/documentation/frontend-login"
date: 2026-09-10
modified: 2026-11-10
---

# Frontend Login

![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        Frontend SSO is switched on per site, in the site configuration:

     Copy

```
```
settings:
  sso_authentication:
    enabled: true
    metadata: 'EXT:my_site_package/Configuration/Sso/frontend.yaml'
    userStoragePid: 42
    loginFormPage: 17
    loginStatusPage: 18
```
```

  `enabled` and `metadata` are both required. Without either, frontend SSO is off for that site and nothing below applies. The remaining keys are in [Configuration](https://b13.com/products/single-sign-on-for-typo3/documentation/configuration#c12338).

   The Contract With Your Own Template
-------------------------------------

**This is the part that changed in 2.0.0.** The extension no longer renders the SSO button. `ModifyFrontendLoginView` listens to EXT:felogin's `ModifyLoginFormViewEvent` and assigns three variables to the login form's view. Everything visual—the button, hiding the password fields, the wording—is your own `Login.html`.

A site that rendered the previously shipped partial by name has a broken login page until its template is updated. This section is what to build instead.

**EXT:felogin is required.** `ModifyLoginFormViewEvent` is declared there, so without `typo3/cms-felogin` installed the event does not exist and the listener never fires. It is not a hard dependency of this extension.

Point felogin at your own template path:

     Copy

```
```
plugin.tx_felogin_login.view.templateRootPaths.20 = EXT:my_site_package/Resources/Private/Templates/Felogin/
```
```

  and put your template at `Templates/Login/Login.html` below that path. Copy `EXT:felogin/Resources/Private/Templates/Login/Login.html` as a starting point.

  ###  The Three Variables

All three are assigned only when SSO is active for the current site. On a site without SSO they are absent, so a template shared across sites needs to cope with that—`f:if` on an undefined variable is false, which is usually enough.

| Variable | Type | Value | Use It To |
|---|---|---|---|
| `additionalAuthenticationProviders` | `array<string, string>` | `['sso-ad' => 'SSO Login']`—a fixed identifier/label pair, not translated and not configurable | Detect that SSO is available, and iterate to render one entry per provider |
| `ssoAcsRedirectUrl` | `TYPO3\CMS\Core\Http\Uri` | The assertion consumer service URL with `?logintype=sso` already appended | Link an `<a>` at it to start a login |
| `enforceSSO` | `bool` | `true` when [`enforceSSO`](#c12382) is set for this site | Hide the username and password fields |

`enforceSSO` in the view is presentation only. The actual rejection of a password login happens during authentication and does not depend on your template getting this right—see [Enforcing SSO](#c12382).

  ###  A Minimal Template

     Copy

```
```
<f:if condition="{additionalAuthenticationProviders}">
    <f:for each="{additionalAuthenticationProviders}" as="label" key="identifier">
        <a href="{ssoAcsRedirectUrl}" class="btn btn-primary btn-block"
           data-provider="{identifier}">{label}</a>
    </f:for>
</f:if>

<f:if condition="{enforceSSO}">
    <f:else>
        <!-- the regular username/password fields, e.g. the partial felogin ships -->
        <f:render partial="Login/LoginForm" arguments="{_all}"/>
    </f:else>
</f:if>
```
```

  Two notes on the markup:

- **Do not hard-code the label.** It comes from the variable, and iterating keeps the template working if a second provider is ever added.
- **`enforceSSO` false does not mean "no SSO".** In that case both blocks render, which is the dual-login case the default is built for.

  ![A frontend login form built with EXT:felogin: a "Login with SSO" button rendered by the site's own Login template above the regular username and password fields, which remain available.](https://b13.com/fileadmin/_processed_/e/3/csm_Documentation-Images-frontend-login-sso-link_7a8d57e241.webp)

   Sending the User Somewhere Specific After Login
-------------------------------------------------

Append `redirect_url` to `ssoAcsRedirectUrl`:

     Copy

```
```
<a href="{ssoAcsRedirectUrl}&redirect_url={f:uri.page(pageUid: 25, absolute: 1)}">
    Login with SSO
</a>
```
```

  The value is carried through the identity provider as the SAML `RelayState` and handed back to felogin as its `referer`, so felogin's `redirect` mode `referer` picks it up. Without it, the visitor comes back to the base of the current site language.

**It has to be an absolute URL.** The value is validated on the way back, not on the way out: a returning `RelayState` is discarded unless its scheme is `http` or `https` **and** its host matches the host the assertion arrived at, which is what keeps it from being used as an open redirect. A relative path has no host and is dropped by the same check, exactly like a URL pointing at another domain—neither produces an error, the visitor just lands on the site base. Hence `absolute: 1` above, and a URI view helper rather than a literal string, so the host always matches the site the visitor is on.

   Enforcing SSO per Site
------------------------

     Copy

```
```
settings:
  sso_authentication:
    enforceSSO: true
```
```

  Defaults to `false`, which offers SSO and the regular login side by side.

With `enforceSSO: true`, **any request without a frontend session is redirected to the identity provider**—not just requests to the login page. The site becomes inaccessible to anonymous visitors, including search engines. That is the point of the setting for an intranet, and a mistake on a public site.

Enforcement is not only a redirect. A password posted at the login form is rejected during authentication, because the SSO authentication service aborts the chain before the username/password service can run. Hiding the fields in the template and rejecting the credentials are two independent mechanisms, and the second is the one that holds.

  **Upgrade note.** Before this setting existed, an SSO-enabled frontend always redirected every visitor to the identity provider—the equivalent of `enforceSSO: true`. The default is now `false`, so a site that wants to keep forcing SSO has to say so explicitly.

  ###  loginFormPage

The page configured as `loginFormPage` is the one exception to the enforced redirect: it renders while logged out, so there is somewhere for the login form to live. **With enforcement on and no `loginFormPage`, every frontend URL bounces to the identity provider**, including the page you wanted to put the form on.

The same page has a second job. When the assertion comes back, TYPO3 has to resolve *some* page for a request addressed to the assertion consumer service path, which is not a page at all. `loginFormPage` is what it resolves, falling back to the site root page when unset. A root page that is a shortcut cannot be used for this.

   A User Without Groups
-----------------------

A logged-in visitor whose only group memberships are the two pseudo-groups every frontend user has—`0` and `-1`—is redirected to `noGroupsPage`. This is the "you have an account here but no access" case, and it is what you get when the identity provider authenticates somebody your `claimsMapping` gives no group to.

Set `noGroupsPage` on any site where that can happen. It is read straight from the site configuration when the case occurs. **Unset, there is no redirect** — the visitor stays on the page they asked for, with whatever the template shows someone without access.

   Logging Out
-------------

`?logintype=slo` on a page of the site starts a single logout: TYPO3 asks the identity provider to end the session, and the TYPO3 session is dropped when the identity provider’s answer comes back. `loginStatusPage` is where a `?logintype=slo` request lands once there is no session left, which is what makes it the page to put a "you are signed out" message on. **Unset, the logout lands on the site’s root page instead.** The three situations the parameter covers, and the order they run in, are in [Single Logout](https://b13.com/products/single-sign-on-for-typo3/documentation/how-it-works#c12359).