Security
This section describes Brightspot's security configuration keys in context.xml
. In addition, as a best practice install Brightspot on an SSL-configured domain that is separate from the sites it publishes.
Automatic user account creation
File upload restrictionsLimiting uploads by file type
Limiting super user access to developer features
Some developer-level features are available through the Brightspot UI, such as the HTML toggle on the rich-text toolbar and the Developer submenu in the navigation menu. Users without a role are by default super users, and have access to all Brightspot features including those at the developer level.
To block super users' access to the developer-level features, set the key brightspot/missingRolePermissions
. The following table describes the attributes associated with this key.
Attribute | Description | Valid Values |
---|---|---|
| Key for blocking super users from accessing developer-level features in the UI. If this key is not set, super users have access to those features. |
|
| Type of the value. |
|
| Features allowed and blocked from super users. | List of features formatted in the SparseSet representation.
|
The following snippet blocks access to all developer-level features—those in the navigation menu and those in widgets.
<Environment name="brightspot/missingRolePermissions" type="java.lang.String" value="+/ -area/developer -area/developer/ -developer/"/>
Session timeout
Password expiration
Password token expiration
The key cms/tool/changePasswordTokenExpirationInHours
configures the number of hours after which a temporary Brightspot-generated password expires. The following table describes the attributes associated with this key.
Attribute | Description | Valid values |
---|---|---|
| Key for specifying number of hours after which a temporary password token expires. If this key is not set, the expiration defaults to 24 hours. |
|
| Type of the value. |
|
| Number of hours after which password token expires. | Any |
The following snippet specifies password token expiration after 48 hours.
<Environment name="cms/tool/changePasswordTokenExpirationInHours" type="java.lang.Long" value="48" />
Password change
Email notification From address
Password reset email interval
The key cms/tool/forgotPasswordIntervalInMinutes
specifies the number of minutes before Brightspot sends another password-reset email to the same user. This option protects Brightspot from processing automated repeated password-reset requests from the same user within an unreasonably short period of time.
The following table describes the attributes associated with this key.
Attribute | Description | Valid values |
---|---|---|
| Key for specifying number of minutes to pass before sending another password email request to the same user. If this key is not set, users can submit password reset requests every five minutes. |
|
| Type of the value. |
|
| Number of minutes to pass before sending another password email request to the same user. | Any |
The following snippet indicates users can submit password reset requests every 15 minutes.
<Environment name="cms/tool/forgotPasswordIntervalInMinutes" type="java.lang.Long" value="15" />
Declaring password policies
The key dari/userPasswordPolicy/
declares available password policies. A password policy validates new or changed passwords for complexity, such as number of characters, character types in the password (alphanumeric, special characters), and if the password can be reused within a period of time. You can declare multiple password policies, and assign one of them to your Brightspot instance.
The following table describes the attributes associated with this key.
Attribute | Description | Valid values |
---|---|---|
| Key for specifying a class that validates a password's complexity. |
|
| Type of the value. |
|
| Class that validates a password's complexity. The class must implement UserPasswordPolicy. | Fully qualified class name that implements |
The following snippet declares two policies for validating password complexity.
<Environment name="dari/userPasswordPolicy/simple/class" type="java.lang.String" value="brightspot.core.tool.SimplePasswordPolicy" /> <Environment name="dari/userPasswordPolicy/hardened/class" type="java.lang.String" value="brightspot.core.tool.HardenedPasswordPolicy" />
Both classes SimplePasswordPolicy
and HardenedPasswordPolicy
must implement UserPasswordPolicy
, as in the following example.
package brightspot.core.tool; import java.util.Map; import com.psddev.dari.util.PasswordException; import com.psddev.dari.util.UserPasswordPolicy; public class SimplePasswordPolicy implements UserPasswordPolicy { @Override public void initialize(String settingsKey, Map<String, Object> settings) { /* Initialization code */ } @Override public void validate(Object user, String password) throws PasswordException { /* Validation code */ } }
Activating a password policy
The key cms/tool/userPasswordPolicy
activates one of the password policies declared with the key dari/userPasswordPolicy/
. The following table describes the attributes associated with this key.
Attribute | Description | Valid values |
---|---|---|
| Key for activating a password policy. If this key is not set, Brightspot does not check users' passwords for complexity. |
|
| Type of the value. |
|
| Class to use for validating a password. | One of the identifiers specified with the key |
The following snippet activates the password policy simple
that was declared in the snippet Declaring available password policies.
<Environment name="cms/tool/userPasswordPolicy" type="java.lang.String" value="simple" />
Limiting password reuse
The key <id>/passwordHistoryLimit
specifies the previous number of passwords to retain for a user's account. You can use this limit to ensure a user does not use a previous password.
The following table describes the attributes associated with this key.
Attribute | Description | Valid values |
---|---|---|
| Key for retaining a user's previous passwords. If this key is not set, Brightspot does not retain any previous passwords. |
|
| Type of the value. |
|
| Number of passwords to retain. | Any |
The following snippet specifies retaining a user's ten previous passwords (including the current one) when the user password policy simple
is activated.
<Environment name="simple/passwordHistoryLimit" type="java.lang.String" value="10" />
Declaring authentication policies
The key dari/authenticationPolicy/
declares available authentication policies. An authentication policy can check if a user object exists corresponding to the username in the login form, if the user's password expired and needs to be reset, and can validate attempted logins from suspicious domain names. You can declare multiple authentication policies, and assign one of them to your Brightspot instance.
The following table describes the attributes associated with this key.
Attribute | Description | Valid values |
---|---|---|
| Key for specifying a class that authenticates an attempted login. |
|
| Type of the value. |
|
| Class that authenticates an attempted login. The class must implement AuthenticationPolicy. | Fully qualified class name. |
The following snippet declares two policies for authenticating attempted logins.
<Environment name="dari/authenticationPolicy/simple/class" type="java.lang.String" value="com.psddev.cms.db.SimpleAuthenticationPolicy" /> <Environment name="dari/authenticationPolicy/hardened/class" type="java.lang.String" value="com.psddev.cms.db.HardenedAuthenticationPolicy" />
Both classes SimpleAuthenticationPolicy
and HardenedAuthenticationPolicy
must implement AuthenticationPolicy
, as in the following example.
package com.psddev.cms.db; import java.util.Map; import com.psddev.dari.util.AuthenticationException; import com.psddev.dari.util.AuthenticationPolicy; public class SimpleAuthenticationPolicy implements AuthenticationPolicy { @Override public ToolUser authenticate(String username, String password) throws AuthenticationException { /* Authentication code that returns a ToolUser object. */ return user; } @Override public void initialize(String settingsKey, Map<String, Object> settings) { /* Initialization code. */ } }
Activating an authentication policy
The key cms/tool/authenticationPolicy
activates one of the password policies declared with the key dari/authenticationPolicy/
. The following table describes the attributes associated with this key.
Attribute | Description | Valid values |
---|---|---|
| Key for activating an authentication policy. If this key is not set, Brightspot checks if the submitted password matches the password associated with the user's account. |
|
| Type of the value. |
|
| Class to use for authenticating a login attempt. | One of the identifiers specified with the key |
The following snippet activates the authentication policy simple
that was declared in the snippet Declaring available authentication policies.
<Environment name="cms/tool/authenticationPolicy" type="java.lang.String" value="simple" />
Password reuse limit
<Environment name="{custom}/passwordHistoryLimit" type="java.lang.String" value="10" override="false" />
Key: {custom}/passwordHistoryLimit
Type: java.lang.String
The number of past passwords to keep for a user. Replace the {custom} placeholder with a value used by a custom password policy that implements com/psddev/dari/util/UserPasswordPolicy. The value is an identifier that is used to look up this configuration setting. If this option is not set, then there is no limit.
Login attempt limit
Toggling production and development environments
The key PRODUCTION
toggles between production and development environments. The following table describes the some of the differences between these environments.
Feature |
|
|
---|---|---|
Debugging | Clients must authenticate against the debugging username and password before accessing the Dari debug tools. For information about configuring the debugging username and password, see Debug tools. | Clients can access the Dari debug tools without logging in. |
| Brightspot serves the actual file | Brightspot serves a dummy text file. |
Debugging emails | Brightspot sends notifications only to subscribers. | Brightspot sends notifications to the configured debugging email addresses in addition to other subscribers. See the table Global settings–Main tab for information about configuring debugging email addresses. |
Caution
If this key is not set, Brightspot assumes a default value of false
and operates in a development environment—along with the associated relaxed security measures. Ensure you explicitly configure this value to true
in production environments.
The following table describes the attributes associated with this key.
Atrribute | Description | Valid values |
---|---|---|
| Key for enabling or disabling production mode. Must be set in all caps. |
|
| Type of the value. |
|
| Enables or disables production mode. |
|
The following snippet configures an instance of Brightspot to run in production mode.
<Environment name="PRODUCTION" type="java.lang.Boolean" value="true" />
Custom authentication policy example
Step 1: Create authentication policy implementation
The following code example shows a custom implementation of AuthenticationPolicy
. CustomAuthenticationPolicy
extends ToolAuthenticationPolicy
. This Brightspot base class does the work of validating user passwords. It also checks if the cms/tool/userPasswordPolicy
key is set with a custom password policy implementation. If it is, ToolAuthenticationPolicy
invokes the implementation to validate the password.
In the event that ToolAuthenticationPolicy
cannot validate the user, CustomAuthenticationPolicy
checks if the user has reached the login-attempt limit. It does this by accessing the value of the cms/tool/userPasswordPolicy
key.
public class CustomAuthenticationPolicy extends ToolAuthenticationPolicy implements AuthenticationPolicy { @Override public ToolUser authenticate(final String username, String password) throws AuthenticationException { ToolUser user = null; try { user = super.authenticate(username, password); } catch (AuthenticationException e) { user = Query.from(ToolUser.class).where("email = ? or username = ?", username, username).first(); if (user != null) { /* Check if the login attempt limit has been reached. */ long loginAttemptLimit = Settings.getOrDefault(long.class, "acme/loginAttemptLimit", 0L); if (loginAttemptLimit > 0 && helperClass.getConsecutiveFailedLogins().size() >= loginAttemptLimit) { throw new AuthenticationException("Too many failed login attempts. Please contact your System Administrator."); } } throw e; } return user; } }
Step 2: Create password policy implementation
A custom password policy implements UserPasswordPolicy
. It typically checks that a new password complies with defined string requirements like length and character type. A password policy can also access the passwordHistoryLimit
key to limit reuse of a password within a defined history limit.
public class CustomPasswordPolicy implements UserPasswordPolicy { @Override public void validate(Object user, String password) throws PasswordException { /* Validate password */ } }
Step 3: Configure custom authentication policy
The Tomcat context.xml
file includes the security keys to configure Brightspot for the custom authentication and password policy implementations.
<Environment name="dari/userPasswordPolicy/acme/class" type="java.lang.String" value="com.acme.auth.CustomPasswordPolicy" override="false" /> 1 <Environment name="cms/tool/userPasswordPolicy" type="java.lang.String" value="acme" override="false" /> <Environment name="dari/authenticationPolicy/acme/class" type="java.lang.String" value="com.acme.auth.CustomAuthenticationPolicy" override="false" /> 2 <Environment name="cms/tool/authenticationPolicy" type="java.lang.String" value="acme" override="false" /> <Environment name="acme/loginAttemptLimit" type="java.lang.String" value="5" override="false" /> 3 <Environment name="acme/passwordHistoryLimit" type="java.lang.String" value="10" override="false" /> 4
Specifies a custom password policy that implements | |
Specifies a custom authentication policy that implements | |
Specifies the login attempt limit, which is read by | |
Specifies the password reuse limit, which is read by |