Version 5 supported

Authentication

By default, Silverstripe CMS provides a MemberAuthenticator class which hooks into its own internal authentication system.

User interface

Silverstripe CMS comes with a default login form interface, that's embedded into your page templates through the $Form placeholder. Since it's embedded into your own site styling and behaviour, it can require adjustments to your particular context.

The view logic may be handled through the silverstripe/login-forms module (if present).

Controllers

The main login system uses these controllers to handle the various security requests:

Security - Which is the controller which handles most front-end security requests, including logging in, logging out, resetting password, or changing password. This class also provides an interface to allow configured Authenticator classes to each display a custom login form.

CMSSecurity - Which is the controller which handles security requests within the CMS, and allows users to re-login without leaving the CMS.

Member authentication

The default member authentication system is implemented in the following classes:

MemberAuthenticator - Which is the default member authentication implementation. This uses the email and password stored internally for each member to authenticate them.

MemberLoginForm - Is the default form used by MemberAuthenticator, and is displayed on the public site at the URL Security/login by default.

CMSMemberLoginForm - Is the secondary form used by MemberAuthenticator, and will be displayed to the user within the CMS any time their session expires or they are logged out via an action. This form is presented via a popup dialog, and can be used to re-authenticate that user automatically without them having to lose their workspace. For example if editing a form, the user can login and continue to publish their content.

Custom authentication

Additional authentication methods (oauth, etc) can be implemented by creating custom implementations of each of the following base classes:

Authenticator - The base class for authentication systems. This class also acts as the factory to generate various login forms for parts of the system. If an authenticator supports in-cms reauthentication then it will be necessary to override the supports_cms and get_cms_login_form methods.

LoginForm - which is the base class for a login form which links to a specific authenticator. At the very least, it will be necessary to implement a form class which provides a default login interface. If in-cms re-authentication is desired, then a specialised subclass of this method may be necessary. For example, this form could be extended to require confirmation of username as well as password.

Default admin

When a new Silverstripe CMS site is created for the first time, it may be necessary to create a default admin to provide CMS access for the first time. Silverstripe CMS provides a default admin configuration system, which allows a username and password to be configured for a single special user outside of the normal membership system.

It is advisable to configure this user in your .env file inside of the project root, as below:

# Configure a default username and password to access the CMS on all sites in this environment.
SS_DEFAULT_ADMIN_USERNAME="admin"
SS_DEFAULT_ADMIN_PASSWORD="password"

When a user logs in with these credentials, then a Member with the Email 'admin' will be generated in the database, but without any password information. This means that the password can be reset or changed by simply updating the .env file.

Registering a new authenticator

SilverStripe\Core\Injector\Injector:
  SilverStripe\Security\Security:
    properties:
      Authenticators:
        myauthenticator: '%$App\Authenticator\MyAuthenticator'

If there is no authenticator registered, Authenticator will try to fall back on the default provided authenticator (default), which can be changed using the following config, replacing the MemberAuthenticator with your authenticator:

---
Name: MyAuth
After:
  - '#coresecurity'
---
SilverStripe\Core\Injector\Injector:
  SilverStripe\Security\Security:
    properties:
      Authenticators:
        default: '%$App\Authenticator\MyAuthenticator'

By default, the SilverStripe\Security\MemberAuthenticator\MemberAuthenticator is seen as the default authenticator until it's explicitly set in the config.

Every Authenticator is expected to handle services. The Authenticator Interface provides the available services:

const LOGIN = 1;
const LOGOUT = 2;
const CHANGE_PASSWORD = 4;
const RESET_PASSWORD = 8;
const CMS_LOGIN = 16;

/**
 * Returns the services supported by this authenticator
 *
 * The number should be a bitwise-OR of 1 or more of the following constants:
 * Authenticator::LOGIN, Authenticator::LOGOUT, Authenticator::CHANGE_PASSWORD,
 * Authenticator::RESET_PASSWORD, or Authenticator::CMS_LOGIN
 *
 * @return int
 */
public function supportedServices();

If there is no available authenticator for the required action (either one of the constants above), an error will be thrown.

Custom Authenticators are expected to have the following methods implemented:

  • getLoginHandler()
  • getLogoutHandler()
  • getChangePasswordHandler()
  • getLostPasswordHandler()

All expect a $link variable, to handle the request. Further, there is

  • authenticate() Which expects the data to be used for authentication as an array and a nullable variable $result by reference, which returns a ValidationResult.

If only a subset of the supportedServices() will be provided by the custom Authenticator, it is advised to extend SilverStripe\Security\MemberAuthenticator\MemberAuthenticator, as that default contains all required methods already and only an override or follow up needs to be written.

An example of how to write a multi-factor authentication can be found here.

IdentityStore

A new IdentityStore, e.g. an LDAP IdentityStore can be registered as follows in a security.yml file (Not an actual valid LDAP configuration):

SilverStripe\Core\Injector\Injector:
  App\LDAP\Authenticator\LDAPAuthenticator:
    properties:
      LDAPSettings:
        - URL: https://my-ldap-location.com
      CascadeInTo: '%$SilverStripe\Security\MemberAuthenticator\SessionAuthenticationHandler'
  SilverStripe\Security\AuthenticationHandler:
    class: SilverStripe\Security\RequestAuthenticationHandler
    properties:
      Handlers:
        ldap: '%$App\LDAP\Authenticator\LDAPAuthenticator'

CascadeInTo is used to defer login or logout actions to other authenticators, after the first one has been logged in. In the example of LDAP authenticator, this is useful to check e.g. the validity of the Session (is the user still logged in?) and if not, or it's LDAP login period has expired, only then validate against the external service again, limiting the amount of requests to the external service.

Upon request, the Member is authenticated against the given AuthenticatorHandlers. To override an Authenticator, override it's name in the YAML to your own Handler.

To get applicable Authenticators for a certain request, refer to Security::getApplicableAuthenticators().

To register CMS authenticators, use the same procedure as above, only replace SilverStripe\Security\Security with SilverStripe\Security\CMSSecurity.