How to Create and Enable Custom User Checkers

During the authentication of a user, additional checks might be required to verify if the identified user is allowed to log in. By defining a custom user checker, you can define per firewall which checker should be used.

ユーザーの認証中に、識別されたユーザーがログインを許可されているかどうかを確認するために、追加のチェックが必要になる場合があります。カスタム ユーザー チェッカーを定義することにより、使用するチェッカーをファイアウォールごとに定義できます。

Creating a Custom User Checker

User checkers are classes that must implement the UserCheckerInterface. This interface defines two methods called checkPreAuth() and checkPostAuth() to perform checks before and after user authentication. If one or more conditions are not met, throw an exception which extends the AccountStatusException class. Consider using CustomUserMessageAccountStatusException, which extends AccountStatusException and allows to customize the error message displayed to the user:

ユーザー チェッカーは、UserCheckerInterface を実装する必要があるクラスです。このインターフェースは、checkPreAuth() および checkPostAuth() と呼ばれる 2 つのメソッドを定義して、ユーザー認証の前後にチェックを実行します。 1 つ以上の条件が満たされない場合は、AccountStatusException クラスを拡張する例外をスローします。AccountStatusException を拡張し、ユーザーに表示されるエラー メッセージをカスタマイズできる CustomUserMessageAccountStatusException の使用を検討してください。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
namespace App\Security;

use App\Entity\User as AppUser;
use Symfony\Component\Security\Core\Exception\AccountExpiredException;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAccountStatusException;
use Symfony\Component\Security\Core\User\UserCheckerInterface;
use Symfony\Component\Security\Core\User\UserInterface;

class UserChecker implements UserCheckerInterface
{
    public function checkPreAuth(UserInterface $user): void
    {
        if (!$user instanceof AppUser) {
            return;
        }

        if ($user->isDeleted()) {
            // the message passed to this exception is meant to be displayed to the user
            throw new CustomUserMessageAccountStatusException('Your user account no longer exists.');
        }
    }

    public function checkPostAuth(UserInterface $user): void
    {
        if (!$user instanceof AppUser) {
            return;
        }

        // user account is expired, the user may be notified
        if ($user->isExpired()) {
            throw new AccountExpiredException('...');
        }
    }
}

Enabling the Custom User Checker

Next, make sure your user checker is registered as a service. If you're using the default services.yaml configuration, the service is registered automatically.

次に、ユーザー チェッカーがサービスとして登録されていることを確認します。デフォルトの services.yaml 構成を使用している場合、サービスは自動的に登録されます。

All that's left to do is add the checker to the desired firewall where the value is the service id of your user checker:

あとは、目的のファイアウォールにチェッカーを追加するだけです。ここで、値はユーザー チェッカーのサービス ID です。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
# config/packages/security.yaml

# ...
security:
    firewalls:
        main:
            pattern: ^/
            user_checker: App\Security\UserChecker
            # ...

Using Multiple User Checkers

6.2

6.2

The ChainUserChecker class was added in Symfony 6.2.

ChainUserChecker クラスは Symfony 6.2 で追加されました。

It is common for applications to have multiple authentication entry points (such as traditional form based login and an API) which may have unique checker rules for each entry point as well as common rules for all entry points. To allow using multiple user checkers on a firewall, a service for the ChainUserChecker class is created for each firewall.

アプリケーションには複数の認証エントリ ポイント (従来のフォーム ベースのログインや API など) があり、各エントリ ポイントに固有のチェッカー ルールと、すべてのエントリ ポイントに共通のルールがあることが一般的です。ファイアウォールで複数のユーザーチェッカーを使用できるようにするために、各ファイアウォールに対して ChainUserCheckerclass のサービスが作成されます。

To use the chain user checker, first you will need to tag your user checker services with the security.user_checker.<firewall> tag (where <firewall> is the name of the firewall in your security configuration). The service tag also supports the priority attribute, allowing you to define the order in which user checkers are called:

チェーン ユーザー チェッカーを使用するには、まずユーザー チェッカー サービスに security.user_checker のタグを付ける必要があります。タグ (セキュリティ構成のファイアウォールの名前)。サービスタグは優先度属性もサポートしているため、ユーザーチェッカーが呼び出される順序を定義できます。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
11
12
# config/services.yaml

# ...
services:
    App\Security\AccountEnabledUserChecker:
        tags:
            - { name: security.user_checker.api, priority: 10 }
            - { name: security.user_checker.main, priority: 10 }

    App\Security\APIAccessAllowedUserChecker:
        tags:
            - { name: security.user_checker.api, priority: 5 }

Once your checker services are tagged, next you will need configure your firewalls to use the security.user_checker.chain.<firewall> service:

チェッカー サービスがタグ付けされたら、次にファイアウォールを設定して security.user_checker.chain を使用する必要があります。サービス:
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
# config/packages/security.yaml

# ...
security:
    firewalls:
        api:
            pattern: ^/api
            user_checker: security.user_checker.chain.api
            # ...
        main:
            pattern: ^/
            user_checker: security.user_checker.chain.main
            # ...