Password policy validators
TYPO3 ships with two password policy validators, which are both used in the default password policy.
CorePasswordValidator
The
\TYPO3\
validator has the ability to ensure a complex password with a defined
minimum length and four individual requirements.
The following options are available:
minimumLength
-
- type
-
int
- Default
-
8
The minimum length of a given password.
upperCaseCharacterRequired
-
- type
-
bool
- Default
-
true
If set to
trueat least one upper case character (A-Z) is required.
lowerCaseCharacterRequired
-
- type
-
bool
- Default
-
true
If set to
trueat least one lower case character (a-z) is required.
digitCharacterRequired
-
- type
-
bool
- Default
-
true
If set to
trueat least one digit character (0-9) is required.
specialCharacterRequired
-
- type
-
bool
- Default
-
true
If set to
trueat least one special character (not0-9,a-z,A-Z) is required.
NotCurrentPasswordValidator
The
\TYPO3\
validator can be used to ensure, that the new user password is not
equal to the old password. The validator must always be configured with
the exclude action
\TYPO3\,
because it should be excluded, when a new user account is created.
Third-party password validators
The extension EXT:add_pwd_policy provides additional validators.
Custom password validator
To create a custom password validator, a new class has to be added which
extends
\TYPO3\.
It is required to overwrite the following functions:
public function initializeRequirements (): void public function validate(string $password, ?Context Data $context Data = null): bool
Please refer to
\TYPO3\
for a detailed implementation example.
Tip
The third-party extension derhansen/add_pwd_policy provides additional password validators. It can also be used as a resource for writing your own password validator.
Using password policy validation in Extbase
If you need to validate a plaintext password within Extbase, for example in a
Data transfer object (DTO),
you can call the
\TYPO3\ from
within a custom validator, for example:
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\Domain\Validator;
use TYPO3\CMS\Core\PasswordPolicy\PasswordPolicyAction;
use TYPO3\CMS\Core\PasswordPolicy\PasswordPolicyValidator;
use TYPO3\CMS\Extbase\Validation\Validator\AbstractValidator;
class ExtbasePasswordPolicyValidator extends AbstractValidator
{
protected function isValid(mixed $value): void
{
if (!is_string($value)) {
return;
}
$passwordValidator = new PasswordPolicyValidator(PasswordPolicyAction::NEW_USER_PASSWORD);
if (!$passwordValidator->isValidPassword($value)) {
foreach ($passwordValidator->getValidationErrors() as $validationError) {
$this->addError($validationError, 1774872344835);
}
}
}
}
The error code should be a unique integer. It is common practice in TYPO3 to use the current Unix timestamp in milliseconds when creating a new validator, as this provides a simple way to generate a unique value.
You can then use your custom Extbase validator in the DTO:
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\Domain\Model\Dto;
use MyVendor\MyExtension\Domain\Validator\ExtbasePasswordPolicyValidator;
use TYPO3\CMS\Extbase\Attribute\Validate;
class UserRegistrationDto
{
#[Validate(ExtbasePasswordPolicyValidator::class)]
public string $plainTextPassword = '';
// Another validator for username
public string $username = '';
}
Warning
The password in the DTO is stored in plaintext, you have to hash the password (see Password hashing) before saving it to the database. Never persist a password that was not properly hashed.
Validate a password manually in PHP
You can use the
\TYPO3\ to validate a
password using the validators configured in
$GLOBALS.
The class cannot be injected as it must be instantiated with an action. Available actions can be found in enum EXT:core/Classes/PasswordPolicy/PasswordPolicyAction.php (GitHub).
In the following example a command to generate a public-private key pair validates the password from user input against the default policy of the current TYPO3 installation.
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\Command;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use TYPO3\CMS\Core\PasswordPolicy\PasswordPolicyAction;
use TYPO3\CMS\Core\PasswordPolicy\PasswordPolicyValidator;
#[AsCommand(
name: 'myextension:generateprivatekey',
description: 'Generates an encrypted private key',
)]
final class PrivateKeyGeneratorCommand extends Command
{
// Implement class MyService
public function __construct(private readonly MyService $myService)
{
parent::__construct();
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$passwort = (string)$io->askHidden(
'Please enter the password to encrypt the key',
);
$passwordValidator = new PasswordPolicyValidator(PasswordPolicyAction::NEW_USER_PASSWORD);
$result = $passwordValidator->isValidPassword($passwort);
if ($result === true) {
$this->myService->generatePrivateKey($passwort);
return Command::SUCCESS;
}
$io->error('The password must adhere to the default password policy.');
return Command::FAILURE;
}
}
Events regarding password policy validation
The following PSR-14 event is available: