Security

Symfony provides many tools to secure your application. Some HTTP-related security tools, like secure session cookies and CSRF protection are provided by default. The SecurityBundle, which you will learn about in this guide, provides all authentication and authorization features needed to secure your application.

Symfony は、アプリケーションを保護するための多くのツールを提供します。安全なセッション Cookie や CSRF 保護などの一部の HTTP 関連のセキュリティ ツールは、デフォルトで提供されています。このガイドで学習する SecurityBundle は、アプリケーションを保護するために必要なすべての認証および承認機能を提供します。

To get started, install the SecurityBundle:

開始するには、SecurityBundle をインストールします。
1
$ composer require symfony/security-bundle

If you have Symfony Flex installed, this also creates a security.yaml configuration file for you:

Symfony Flex がインストールされている場合、これにより security.yaml 構成ファイルも作成されます。
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
# config/packages/security.yaml
security:
    # https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
    password_hashers:
        Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
    # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
    providers:
        users_in_memory: { memory: null }
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            lazy: true
            provider: users_in_memory

            # activate different ways to authenticate
            # https://symfony.com/doc/current/security.html#firewalls-authentication

            # https://symfony.com/doc/current/security/impersonating_user.html
            # switch_user: true

    # Easy way to control access for large sections of your site
    # Note: Only the *first* access control that matches will be used
    access_control:
        # - { path: ^/admin, roles: ROLE_ADMIN }
        # - { path: ^/profile, roles: ROLE_USER }

That's a lot of config! In the next sections, the three main elements are discussed:

それはたくさんの設定です!次のセクションでは、次の 3 つの主要な要素について説明します。
The User (providers)
Any secured section of your application needs some concept of a user. The user provider loads users from any storage (e.g. the database) based on a "user identifier" (e.g. the user's email address);
アプリケーションのセキュリティで保護されたセクションには、ユーザーの概念が必要です。ユーザープロバイダーは、「ユーザー識別子」(ユーザーの電子メールアドレスなど)に基づいて、任意のストレージ(データベースなど)からユーザーをロードします。
The Firewall & Authenticating Users (firewalls)
The firewall is the core of securing your application. Every request within the firewall is checked if it needs an authenticated user. The firewall also takes care of authenticating this user (e.g. using a login form);
ファイアウォールは、アプリケーションを保護するための中核です。認証されたユーザーが必要かどうか、ファイアウォール内のすべての要求がチェックされます。ファイアウォールは、このユーザーの認証も処理します (例: ログインフォームを使用)。
Access Control (Authorization) (access_control)
Using access control and the authorization checker, you control the required permissions to perform a specific action or visit a specific URL.
アクセス制御と承認チェッカーを使用して、特定のアクションを実行したり、特定の URL にアクセスしたりするために必要なアクセス許可を制御します。

The User

Permissions in Symfony are always linked to a user object. If you need to secure (parts of) your application, you need to create a user class. This is a class that implements UserInterface. This is often a Doctrine entity, but you can also use a dedicated Security user class.

Symfony のパーミッションは、常にユーザー オブジェクトにリンクされています。アプリケーション (の一部) を保護する必要がある場合は、ユーザー クラスを作成する必要があります。これは UserInterface を実装するクラスです。これは多くの場合 Doctrine エンティティですが、dedicatedSecurity ユーザー クラスを使用することもできます。

The easiest way to generate a user class is using the make:user command from the MakerBundle:

ユーザー クラスを生成する最も簡単な方法は、MakerBundle の make:user コマンドを使用することです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ php bin/console make:user
 The name of the security user class (e.g. User) [User]:
 > User

 Do you want to store user data in the database (via Doctrine)? (yes/no) [yes]:
 > yes

 Enter a property name that will be the unique "display" name for the user (e.g. email, username, uuid) [email]:
 > email

 Will this app need to hash/check user passwords? Choose No if passwords are not needed or will be checked/hashed by some other system (e.g. a single sign-on server).

 Does this app need to hash/check user passwords? (yes/no) [yes]:
 > yes

 created: src/Entity/User.php
 created: src/Repository/UserRepository.php
 updated: src/Entity/User.php
 updated: config/packages/security.yaml
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// src/Entity/User.php
namespace App\Entity;

use App\Repository\UserRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;

#[ORM\Entity(repositoryClass: UserRepository::class)]
class User implements UserInterface, PasswordAuthenticatedUserInterface
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    private $id;

    #[ORM\Column(type: 'string', length: 180, unique: true)]
    private $email;

    #[ORM\Column(type: 'json')]
    private $roles = [];

    #[ORM\Column(type: 'string')]
    private $password;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getEmail(): ?string
    {
        return $this->email;
    }

    public function setEmail(string $email): self
    {
        $this->email = $email;

        return $this;
    }

    /**
     * The public representation of the user (e.g. a username, an email address, etc.)
     *
     * @see UserInterface
     */
    public function getUserIdentifier(): string
    {
        return (string) $this->email;
    }

    /**
     * @see UserInterface
     */
    public function getRoles(): array
    {
        $roles = $this->roles;
        // guarantee every user at least has ROLE_USER
        $roles[] = 'ROLE_USER';

        return array_unique($roles);
    }

    public function setRoles(array $roles): self
    {
        $this->roles = $roles;

        return $this;
    }

    /**
     * @see PasswordAuthenticatedUserInterface
     */
    public function getPassword(): string
    {
        return $this->password;
    }

    public function setPassword(string $password): self
    {
        $this->password = $password;

        return $this;
    }

    /**
     * Returning a salt is only needed if you are not using a modern
     * hashing algorithm (e.g. bcrypt or sodium) in your security.yaml.
     *
     * @see UserInterface
     */
    public function getSalt(): ?string
    {
        return null;
    }

    /**
     * @see UserInterface
     */
    public function eraseCredentials()
    {
        // If you store any temporary, sensitive data on the user, clear it here
        // $this->plainPassword = null;
    }
}

If your user is a Doctrine entity, like in the example above, don't forget to create the tables by creating and running a migration:

上記の例のように、ユーザーが Doctrine エンティティである場合は、移行を作成して実行することでテーブルを作成することを忘れないでください:
1
2
$ php bin/console make:migration
$ php bin/console doctrine:migrations:migrate

Loading the User: The User Provider

Besides creating the entity, the make:user command also adds config for a user provider in your security configuration:

エンティティを作成するだけでなく、make:user コマンドは、セキュリティ構成にユーザー プロバイダーの構成も追加します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
# config/packages/security.yaml
security:
    # ...

    providers:
        app_user_provider:
            entity:
                class: App\Entity\User
                property: email

This user provider knows how to (re)load users from a storage (e.g. a database) based on a "user identifier" (e.g. the user's email address or username). The configuration above uses Doctrine to load the User entity using the email property as "user identifier".

このユーザー プロバイダーは、"ユーザー識別子" (ユーザーの電子メール アドレスやユーザー名など) に基づいてストレージ (データベースなど) からユーザーを (再) ロードする方法を知っています。 「ユーザー識別子」。

User providers are used in a couple places during the security lifecycle:

ユーザー プロバイダーは、セキュリティ ライフサイクルのいくつかの場所で使用されます。
Load the User based on an identifier
During login (or any other authenticator), the provider loads the user based on the user identifier. Some other features, like user impersonation and Remember Me also use this.
ログイン中 (またはその他のオーセンティケーター)、プロバイダーはユーザー ID に基づいてユーザーをロードします。ユーザーの偽装やRemember Meなどの他の機能もこれを使用します。
Reload the User from the session
At the beginning of each request, the user is loaded from the session (unless your firewall is stateless). The provider "refreshes" the user (e.g. the database is queried again for fresh data) to make sure all user information is up to date (and if necessary, the user is de-authenticated/logged out if something changed). See Security for more information about this process.
各リクエストの開始時に、ユーザーはセッションからロードされます (ファイアウォールがステートレスでない限り)。プロバイダーは、すべてのユーザー情報が最新であることを確認するために、ユーザーを「更新」します (たとえば、データベースに新しいデータを再度照会します)。このプロセスの詳細については、セキュリティを参照してください。

Symfony comes with several built-in user providers:

symfony には、いくつかの組み込みのユーザー プロバイダーが付属しています。
Entity User Provider
Loads users from a database using Doctrine;
Doctrine を使用してデータベースからユーザーをロードします。
LDAP User Provider
Loads users from a LDAP server;
LDAP サーバーからユーザーをロードします。
Memory User Provider
Loads users from a configuration file;
構成ファイルからユーザーをロードします。
Chain User Provider
Merges two or more user providers into a new user provider. Since each firewall has exactly one user provider, you can use this to chain multiple providers together.
2 つ以上のユーザー プロバイダーを新しいユーザー プロバイダーにマージします。各ファイアウォールにはユーザー プロバイダーが 1 つだけあるため、これを使用して複数のプロバイダーを連鎖させることができます。

The built-in user providers cover the most common needs for applications, but you can also create your own custom user provider.

組み込みのユーザー プロバイダーは、アプリケーションの最も一般的なニーズをカバーしますが、独自のカスタム ユーザー プロバイダーを作成することもできます。

Note

ノート

Sometimes, you need to inject the user provider in another class (e.g. in your custom authenticator). All user providers follow this pattern for their service ID: security.user.provider.concrete.<your-provider-name> (where <your-provider-name> is the configuration key, e.g. app_user_provider). If you only have one user provider, you can autowire it using the UserProviderInterface type-hint.

場合によっては、ユーザー プロバイダーを別のクラス (カスタム オーセンティケーターなど) に挿入する必要があります。すべてのユーザー プロバイダーは、サービス ID について次のパターンに従います: security.user.provider.concrete.(app_user_provider などの構成キー)。ユーザー プロバイダーが 1 つしかない場合は、UserProviderInterfacetype-hint を使用して自動配線できます。

Registering the User: Hashing Passwords

Many applications require a user to log in with a password. For these applications, the SecurityBundle provides password hashing and verification functionality.

多くのアプリケーションでは、ユーザーはパスワードでログインする必要があります。これらのアプリケーションに対して、SecurityBundle はパスワードのハッシュと検証機能を提供します。

First, make sure your User class implements the PasswordAuthenticatedUserInterface:

まず、 User クラスが thePasswordAuthenticatedUserInterface を実装していることを確認してください。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// src/Entity/User.php

// ...
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;

class User implements UserInterface, PasswordAuthenticatedUserInterface
{
    // ...

    /**
     * @return string the hashed password for this user
     */
    public function getPassword(): string
    {
        return $this->password;
    }
}

Then, configure which password hasher should be used for this class. If your security.yaml file wasn't already pre-configured, then make:user should have done this for you:

次に、このクラスに使用するパスワード ハッシャーを構成します。 security.yaml ファイルがまだ事前構成されていない場合は、make:user がこれを行う必要があります。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
# config/packages/security.yaml
security:
    # ...
    password_hashers:
        # Use native password hasher, which auto-selects and migrates the best
        # possible hashing algorithm (which currently is "bcrypt")
        Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'

Now that Symfony knows how you want to hash the passwords, you can use the UserPasswordHasherInterface service to do this before saving your users to the database:

パスワードをハッシュする方法を Symfony が認識したので、ユーザーをデータベースに保存する前に、UserPasswordHasherInterface サービスを使用してこれを行うことができます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// src/Controller/RegistrationController.php
namespace App\Controller;

// ...
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;

class RegistrationController extends AbstractController
{
    public function index(UserPasswordHasherInterface $passwordHasher)
    {
        // ... e.g. get the user data from a registration form
        $user = new User(...);
        $plaintextPassword = ...;

        // hash the password (based on the security.yaml config for the $user class)
        $hashedPassword = $passwordHasher->hashPassword(
            $user,
            $plaintextPassword
        );
        $user->setPassword($hashedPassword);

        // ...
    }
}

Tip

ヒント

The make:registration-form maker command can help you set-up the registration controller and add features like email address verification using the SymfonyCastsVerifyEmailBundle.

make:registration-form maker コマンドは、登録コントローラーをセットアップし、SymfonyCastsVerifyEmailBundle を使用してメールアドレス検証などの機能を追加するのに役立ちます。
1
2
$ composer require symfonycasts/verify-email-bundle
$ php bin/console make:registration-form

You can also manually hash a password by running:

次のコマンドを実行して、パスワードを手動でハッシュすることもできます。
1
$ php bin/console security:hash-password

Read more about all available hashers and password migration in Password Hashing and Verification.

利用可能なすべてのハッシャーとパスワードの移行について詳しくは、パスワードのハッシュと検証をご覧ください。

6.2

6.2

In applications using Symfony 6.2 and PHP 8.2 or newer, the SensitiveParameter PHP attribute is applied to all plain passwords and sensitive tokens so they don't appear in stack traces.

Symfony 6.2 および PHP 8.2 以降を使用するアプリケーションでは、SensitiveParameter PHP 属性がすべてのプレーン パスワードと機密トークンに適用されるため、それらはスタック トレースに表示されません。

The Firewall

The firewalls section of config/packages/security.yaml is the most important section. A "firewall" is your authentication system: the firewall defines which parts of your application are secured and how your users will be able to authenticate (e.g. login form, API token, etc).

config/packages/security.yaml のファイアウォール セクションは、最も重要なセクションです。 「ファイアウォール」は認証システムです。ファイアウォールは、アプリケーションのどの部分を保護し、ユーザーがどのように認証できるか (ログイン フォーム、API トークンなど) を定義します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# config/packages/security.yaml
security:
    # ...
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            lazy: true
            # provider that you set earlier inside providers
            provider: app_user_provider

            # activate different ways to authenticate
            # https://symfony.com/doc/current/security.html#firewalls-authentication

            # https://symfony.com/doc/current/security/impersonating_user.html
            # switch_user: true

Only one firewall is active on each request: Symfony uses the pattern key to find the first match (you can also match by host or other things).

リクエストごとに 1 つのファイアウォールのみがアクティブになります。symfony はパターン キーを使用して最初の一致を見つけます (ホストまたはその他のもので一致させることもできます)。

The dev firewall is really a fake firewall: it makes sure that you don't accidentally block Symfony's dev tools - which live under URLs like /_profiler and /_wdt.

dev ファイアウォールは本当に偽のファイアウォールです: Symfony の開発ツールを誤ってブロックしないようにします。

All real URLs are handled by the main firewall (no pattern key means it matches all URLs). A firewall can have many modes of authentication, in other words, it enables many ways to ask the question "Who are you?".

すべての実際の URL は、メインのファイアウォールによって処理されます (パターン キーがないということは、すべての URL に一致することを意味します)。ファイアウォールは、多くの認証モードを持つことができます。言い換えれば、「あなたは誰ですか?」という質問をさまざまな方法で行うことができます。

Often, the user is unknown (i.e. not logged in) when they first visit your website. If you visit your homepage right now, you will have access and you'll see that you're visiting a page behind the firewall in the toolbar:

多くの場合、ユーザーが最初に Web サイトにアクセスしたとき、そのユーザーは不明です (つまり、ログインしていません)。今すぐホームページにアクセスすると、アクセスできるようになり、ツールバーのファイアウォールの背後にあるページにアクセスしていることがわかります。

Visiting a URL under a firewall doesn't necessarily require you to be authenticated (e.g. the login form has to be accessible or some parts of your application are public). You'll learn how to restrict access to URLs, controllers or anything else within your firewall in the access control section.

ファイアウォールの下にある URL にアクセスするために、必ずしも認証が必要というわけではありません (たとえば、ログイン フォームにアクセスできる必要があるか、アプリケーションの一部が公開されている必要があります)。アクセス制御セクションで、URL、コントローラー、またはファイアウォール内のその他のものへのアクセスを制限する方法を学びます。

Tip

ヒント

The lazy anonymous mode prevents the session from being started if there is no need for authorization (i.e. explicit check for a user privilege). This is important to keep requests cacheable (see HTTP Cache).

レイジー匿名モードでは、承認が必要ない場合 (つまり、ユーザー権限の明示的なチェック)、セッションが開始されません。これは、リクエストをキャッシュ可能に保つために重要です (HTTP キャッシュを参照)。

Note

ノート

If you do not see the toolbar, install the profiler with:

ツールバーが表示されない場合は、次のようにプロファイラーをインストールします。
1
$ composer require --dev symfony/profiler-pack

Fetching the Firewall Configuration for a Request

If you need to get the configuration of the firewall that matched a given request, use the Security service:

特定の要求に一致するファイアウォールの構成を取得する必要がある場合は、セキュリティ サービスを使用します。
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
// src/Service/ExampleService.php
// ...

use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\RequestStack;

class ExampleService
{
    private Security $security;

    public function __construct(Security $security, RequestStack $requestStack)
    {
        $this->requestStack = $requestStack;
        // Avoid calling getFirewallConfig() in the constructor: auth may not
        // be complete yet. Instead, store the entire Security object.
        $this->security = $security;
    }

    public function someMethod()
    {
        $request = $this->requestStack->getCurrentRequest();
        $firewallName = $this->security->getFirewallConfig($request)?->getName();

        // ...
    }
}

6.2

6.2

The getFirewallConfig() method was introduced in Symfony 6.2.

getFirewallConfig() メソッドは Symfony 6.2 で導入されました。

Authenticating Users

During authentication, the system tries to find a matching user for the visitor of the webpage. Traditionally, this was done using a login form or a HTTP basic dialog in the browser. However, the SecurityBundle comes with many other authenticators:

認証中、システムは Web ページの訪問者に一致するユーザーを見つけようとします。従来、これはブラウザのログイン フォームまたは HTTP 基本ダイアログを使用して行われていました。ただし、SecurityBundle には他の多くのオーセンティケーターが付属しています。

Tip

ヒント

If your application logs users in via a third-party service such as Google, Facebook or Twitter (social login), check out the HWIOAuthBundle community bundle.

アプリケーションが Google、Facebook、Twitter (ソーシャル ログイン) などのサードパーティ サービスを介してユーザーをログインさせる場合は、HWIOAuthBundlecommunity バンドルを確認してください。

Form Login

Most websites have a login form where users authenticate using an identifier (e.g. email address or username) and a password. This functionality is provided by the form login authenticator.

ほとんどの Web サイトには、ユーザーが識別子 (電子メール アドレスやユーザー名など) とパスワードを使用して認証するログイン フォームがあります。この機能は、フォーム ログイン認証システムによって提供されます。

First, create a controller for the login form:

まず、ログイン フォームのコントローラーを作成します。
1
2
3
4
$ php bin/console make:controller Login

 created: src/Controller/LoginController.php
 created: templates/login/index.html.twig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// src/Controller/LoginController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class LoginController extends AbstractController
{
    #[Route('/login', name: 'app_login')]
    public function index(): Response
    {
        return $this->render('login/index.html.twig', [
            'controller_name' => 'LoginController',
        ]);
    }
}

Then, enable the form login authenticator using the form_login setting:

次に、form_login 設定を使用してフォーム ログイン認証を有効にします。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
11
# config/packages/security.yaml
security:
    # ...

    firewalls:
        main:
            # ...
            form_login:
                # "app_login" is the name of the route created previously
                login_path: app_login
                check_path: app_login

Note

ノート

The login_path and check_path support URLs and route names (but cannot have mandatory wildcards - e.g. /login/{foo} where foo has no default value).

login_path と check_path は、URL とルート名をサポートします (ただし、必須のワイルドカードを使用することはできません。たとえば、foo にはデフォルト値がない /login/{foo} など)。

Once enabled, the security system redirects unauthenticated visitors to the login_path when they try to access a secured place (this behavior can be customized using authentication entry points).

有効にすると、認証されていない訪問者が安全な場所にアクセスしようとすると、セキュリティ システムによって login_path にリダイレクトされます (この動作は、認証エントリ ポイントを使用してカスタマイズできます)。

Edit the login controller to render the login form:

ログイン コントローラを編集して、ログイン フォームをレンダリングします。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// ...
+ use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;

  class LoginController extends AbstractController
  {
      #[Route('/login', name: 'app_login')]
-     public function index(): Response
+     public function index(AuthenticationUtils $authenticationUtils): Response
      {
+         // get the login error if there is one
+         $error = $authenticationUtils->getLastAuthenticationError();
+
+         // last username entered by the user
+         $lastUsername = $authenticationUtils->getLastUsername();
+
          return $this->render('login/index.html.twig', [
-             'controller_name' => 'LoginController',
+             'last_username' => $lastUsername,
+             'error'         => $error,
          ]);
      }
  }

Don't let this controller confuse you. Its job is only to render the form: the form_login authenticator will handle the form submission automatically. If the user submits an invalid email or password, that authenticator will store the error and redirect back to this controller, where we read the error (using AuthenticationUtils) so that it can be displayed back to the user.

このコントローラーで混乱させないでください。その仕事はフォームをレンダリングすることだけです: form_login オーセンティケーターはフォームの送信を自動的に処理します.ユーザーが無効な電子メールまたはパスワードを送信した場合、そのオーセンティケーターはエラーを保存し、このコントローラーにリダイレクトして戻します.そこでエラーを読み取ります (AuthenticationUtils を使用)ユーザーに表示できるようにします。

Finally, create or update the template:

最後に、テンプレートを作成または更新します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{# templates/login/index.html.twig #}
{% extends 'base.html.twig' %}

{# ... #}

{% block body %}
    {% if error %}
        <div>{{ error.messageKey|trans(error.messageData, 'security') }}</div>
    {% endif %}

    <form action="{{ path('app_login') }}" method="post">
        <label for="username">Email:</label>
        <input type="text" id="username" name="_username" value="{{ last_username }}">

        <label for="password">Password:</label>
        <input type="password" id="password" name="_password">

        {# If you want to control the URL the user is redirected to on success
        <input type="hidden" name="_target_path" value="/account"> #}

        <button type="submit">login</button>
    </form>
{% endblock %}

Caution

注意

The error variable passed into the template is an instance of AuthenticationException. It may contain sensitive information about the authentication failure. Never use error.message: use the messageKey property instead, as shown in the example. This message is always safe to display.

テンプレートに渡される error 変数は、AuthenticationException のインスタンスです。認証の失敗に関する機密情報が含まれている場合があります。error.message は使用しないでください。例に示すように、代わりに messageKey プロパティを使用してください。このメッセージは常に安全に表示できます。

The form can look like anything, but it usually follows some conventions:

フォームは何にでも似ていますが、通常はいくつかの規則に従います。
  • The <form> element sends a POST request to the app_login route, since that's what you configured as the check_path under the form_login key in security.yaml;
    この要素は app_login ルートに POST リクエストを送信します。
  • The username (or whatever your user's "identifier" is, like an email) field has the name _username and the password field has the name _password.
    ユーザー名 (または電子メールなどのユーザーの「識別子」) フィールドの名前は _username で、パスワード フィールドの名前は _password です。

Tip

ヒント

Actually, all of this can be configured under the form_login key. See Security Configuration Reference (SecurityBundle) for more details.

実際、これらはすべて form_login キーの下で設定できます。詳細については、セキュリティ構成リファレンス (SecurityBundle) を参照してください。

Caution

注意

This login form is currently not protected against CSRF attacks. Read Security on how to protect your login form.

このログイン フォームは現在、CSRF 攻撃から保護されていません。ログインフォームを保護する方法については、ReadSecurity を参照してください。

And that's it! When you submit the form, the security system automatically reads the _username and _password POST parameter, loads the user via the user provider, checks the user's credentials and either authenticates the user or sends them back to the login form where the error can be displayed.

以上です!フォームを送信すると、セキュリティ システムは自動的に _username と _password POST パラメーターを読み取り、ユーザー プロバイダーを介してユーザーを読み込み、ユーザーの資格情報をチェックし、ユーザーを認証するか、エラーを表示できるログイン フォームに送り返します。

To review the whole process:

プロセス全体を確認するには:
  1. The user tries to access a resource that is protected (e.g. /admin);
    ユーザーが保護されているリソース (/admin など) にアクセスしようとしています。
  2. The firewall initiates the authentication process by redirecting the user to the login form (/login);
    ファイアウォールは、ユーザーをログイン フォーム (/login) にリダイレクトすることにより、認証プロセスを開始します。
  3. The /login page renders login form via the route and controller created in this example;
    /login ページは、この例で作成されたルートとコントローラーを介してログイン フォームをレンダリングします。
  4. The user submits the login form to /login;
    ユーザーはログイン フォームを /login に送信します。
  5. The security system (i.e. the form_login authenticator) intercepts the request, checks the user's submitted credentials, authenticates the user if they are correct, and sends the user back to the login form if they are not.
    セキュリティ システム (つまり、form_login オーセンティケーター) は、要求をインターセプトし、ユーザーが送信した資格情報をチェックし、正しい場合はユーザーを認証し、正しくない場合はユーザーをログイン フォームに送り返します。

See also

こちらもご覧ください

You can customize the responses on a successful or failed login attempt. See Customizing the Form Login Authenticator Responses.

ログイン試行の成功または失敗に対する応答をカスタマイズできます。フォーム ログイン認証応答のカスタマイズを参照してください。

CSRF Protection in Login Forms

Login CSRF attacks can be prevented using the same technique of adding hidden CSRF tokens into the login forms. The Security component already provides CSRF protection, but you need to configure some options before using it.

ログイン CSRF 攻撃は、hiddenCSRF トークンをログイン フォームに追加するのと同じ手法を使用して防ぐことができます。 Security コンポーネントはすでに CSRFprotection を提供していますが、使用する前にいくつかのオプションを構成する必要があります。

First, you need to enable CSRF on the form login:

まず、フォーム ログインで CSRF を有効にする必要があります。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
# config/packages/security.yaml
security:
    # ...

    firewalls:
        secured_area:
            # ...
            form_login:
                # ...
                enable_csrf: true

Then, use the csrf_token() function in the Twig template to generate a CSRF token and store it as a hidden field of the form. By default, the HTML field must be called _csrf_token and the string used to generate the value must be authenticate:

次に、Twig テンプレートで csrf_token() 関数を使用して CSRFtoken を生成し、フォームの隠しフィールドとして保存します。デフォルトでは、HTML フィールドは _csrf_token と呼ばれ、値の生成に使用される文字列は認証されている必要があります。
1
2
3
4
5
6
7
8
9
10
{# templates/login/index.html.twig #}

{# ... #}
<form action="{{ path('app_login') }}" method="post">
    {# ... the login fields #}

    <input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">

    <button type="submit">login</button>
</form>

After this, you have protected your login form against CSRF attacks.

この後、ログイン フォームを CSRF 攻撃から保護しました。

Tip

ヒント

You can change the name of the field by setting csrf_parameter and change the token ID by setting csrf_token_id in your configuration. See Security Configuration Reference (SecurityBundle) for more details.

csrf_parameter を設定してフィールドの名前を変更し、構成で csrf_token_id を設定してトークン ID を変更できます。詳細については、セキュリティ構成リファレンス (SecurityBundle) を参照してください。

JSON Login

Some applications provide an API that is secured using tokens. These applications may use an endpoint that provides these tokens based on a username (or email) and password. The JSON login authenticator helps you create this functionality.

一部のアプリケーションは、トークンを使用して保護される API を提供します。これらのアプリケーションは、ユーザー名 (または電子メール) とパスワードに基づいてこれらのトークンを提供するエンドポイントを使用する場合があります。 JSON ログイン認証は、この機能の作成に役立ちます。

Enable the authenticator using the json_login setting:

json_login 設定を使用してオーセンティケーターを有効にします。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
# config/packages/security.yaml
security:
    # ...

    firewalls:
        main:
            # ...
            json_login:
                # api_login is a route we will create below
                check_path: api_login

Note

ノート

The check_path supports URLs and route names (but cannot have mandatory wildcards - e.g. /login/{foo} where foo has no default value).

check_path は URL とルート名をサポートします (ただし、必須のワイルドカードを使用することはできません。たとえば、foo にデフォルト値がない /login/{foo} など)。

The authenticator runs when a client requests the check_path. First, create a controller for this path:

オーセンティケーターは、クライアントが check_path を要求したときに実行されます。まず、このパスのコントローラーを作成します。
1
2
3
$ php bin/console make:controller --no-template ApiLogin

 created: src/Controller/ApiLoginController.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// src/Controller/ApiLoginController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class ApiLoginController extends AbstractController
{
    #[Route('/api/login', name: 'api_login')]
    public function index(): Response
    {
        return $this->json([
            'message' => 'Welcome to your new controller!',
            'path' => 'src/Controller/ApiLoginController.php',
        ]);
    }
}

This login controller will be called after the authenticator successfully authenticates the user. You can get the authenticated user, generate a token (or whatever you need to return) and return the JSON response:

このログイン コントローラーは、オーセンティケーターがユーザーの認証に成功した後に呼び出されます。認証されたユーザーを取得し、トークン (または返す必要があるもの) を生成し、JSON 応答を返すことができます。
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
// ...
+ use App\Entity\User;
+ use Symfony\Component\Security\Http\Attribute\CurrentUser;

  class ApiLoginController extends AbstractController
  {
      #[Route('/api/login', name: 'api_login')]
-     public function index(): Response
+     public function index(#[CurrentUser] ?User $user): Response
      {
+         if (null === $user) {
+             return $this->json([
+                 'message' => 'missing credentials',
+             ], Response::HTTP_UNAUTHORIZED);
+         }
+
+         $token = ...; // somehow create an API token for $user
+
          return $this->json([
-             'message' => 'Welcome to your new controller!',
-             'path' => 'src/Controller/ApiLoginController.php',
+             'user'  => $user->getUserIdentifier(),
+             'token' => $token,
          ]);
      }
  }

Note

ノート

The #[CurrentUser] can only be used in controller arguments to retrieve the authenticated user. In services, you would use getUser().

#[CurrentUser] は、認証されたユーザーを取得するためのコントローラー引数でのみ使用できます。サービスでは、getUser() を使用します。

That's it! To summarize the process:

それでおしまい!プロセスを要約すると、次のようになります。
  1. A client (e.g. the front-end) makes a POST request with the Content-Type: application/json header to /api/login with username (even if your identifier is actually an email) and password keys:

    クライアント (フロントエンドなど) は、Content-Type: application/json ヘッダーを使用して、ユーザー名 (識別子が実際には電子メールであっても) とパスワード キーを使用して /api/login に POST 要求を行います。
    1
    2
    3
    4
    {
        "username": "dunglas@example.com",
        "password": "MyPassword"
    }
  2. The security system intercepts the request, checks the user's submitted credentials and authenticates the user. If the credentials are incorrect, an HTTP 401 Unauthorized JSON response is returned, otherwise your controller is run;
    セキュリティ システムは要求を傍受し、ユーザーが送信した資格情報をチェックして、ユーザーを認証します。資格情報が正しくない場合、HTTP 401 Unauthorized JSON 応答が返されます。それ以外の場合は、コントローラーが実行されます。
  3. Your controller creates the correct response:

    コントローラーは正しい応答を作成します。
    1
    2
    3
    4
    {
        "user": "dunglas@example.com",
        "token": "45be42..."
    }

Tip

ヒント

The JSON request format can be configured under the json_login key. See Security Configuration Reference (SecurityBundle) for more details.

JSON 要求形式は、json_login キーで構成できます。詳細については、セキュリティ構成リファレンス (SecurityBundle) を参照してください。

HTTP Basic

HTTP Basic authentication is a standardized HTTP authentication framework. It asks credentials (username and password) using a dialog in the browser and the HTTP basic authenticator of Symfony will verify these credentials.

HTTP 基本認証は、標準化された HTTP 認証フレームワークです。ブラウザーのダイアログを使用して資格情報 (ユーザー名とパスワード) を要求し、Symfony の HTTP 基本オーセンティケーターがその資格情報を検証します。

Add the http_basic key to your firewall to enable HTTP Basic authentication:

http_basic キーをファイアウォールに追加して、HTTP 基本認証を有効にします。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
# config/packages/security.yaml
security:
    # ...

    firewalls:
        main:
            # ...
            http_basic:
                realm: Secured Area

That's it! Whenever an unauthenticated user tries to visit a protected page, Symfony will inform the browser that it needs to start HTTP basic authentication (using the WWW-Authenticate response header). Then, the authenticator verifies the credentials and authenticates the user.

それでおしまい!認証されていないユーザーが保護されたページにアクセスしようとすると、Symfony はブラウザーに HTTP 基本認証を開始する必要があることを通知します (WWW-Authenticate 応答ヘッダーを使用)。次に、認証者は資格情報を検証し、ユーザーを認証します。

Note

ノート

You cannot use log out with the HTTP basic authenticator. Even if you log out from Symfony, your browser "remembers" your credentials and will send them on every request.

HTTPbasic オーセンティケーターではログアウトを使用できません。 Symfony からログアウトしても、ブラウザーは資格情報を「記憶」しており、リクエストごとにそれらを送信します。

Login links are a passwordless authentication mechanism. The user will receive a short-lived link (e.g. via email) which will authenticate them to the website.

ログイン リンクは、パスワードのない認証メカニズムです。ユーザーは、Web サイトへの認証を行う一時的なリンクを (電子メールなどで) 受け取ります。

You can learn all about this authenticator in How to use Passwordless Login Link Authentication.

このオーセンティケーターの詳細については、パスワードなしのログイン リンク認証の使用方法を参照してください。

Access Tokens

Access Tokens are often used in API contexts. The user receives a token from an authorization server which authenticates them.

アクセス トークンは、API コンテキストでよく使用されます。ユーザーは、ユーザーを認証する承認サーバーからトークンを受け取ります。

You can learn all about this authenticator in How to use Access Token Authentication.

このオーセンティケーターの詳細については、アクセス トークン認証の使用方法を参照してください。

X.509 Client Certificates

When using client certificates, your web server does all the authentication itself. The X.509 authenticator provided by Symfony extracts the email from the "distinguished name" (DN) of the client certificate. Then, it uses this email as user identifier in the user provider.

クライアント証明書を使用する場合、Web サーバーはすべての認証自体を行います。 Symfony が提供する X.509 オーセンティケーターは、クライアント証明書の「識別名」(DN) から電子メールを抽出します。次に、この電子メールをユーザー プロバイダーのユーザー識別子として使用します。

First, configure your web server to enable client certificate verification and to expose the certificate's DN to the Symfony application:

まず、Web サーバーを構成して、クライアント証明書の検証を有効にし、証明書の DN を Symfony アプリケーションに公開します。
  • Nginx
    ニンクス
  • Apache
    アパッチ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
server {
    # ...

    ssl_client_certificate /path/to/my-custom-CA.pem;

    # enable client certificate verification
    ssl_verify_client optional;
    ssl_verify_depth 1;

    location / {
        # pass the DN as "SSL_CLIENT_S_DN" to the application
        fastcgi_param SSL_CLIENT_S_DN $ssl_client_s_dn;

        # ...
    }
}

Then, enable the X.509 authenticator using x509 on your firewall:

次に、ファイアウォールで x509 を使用して X.509 オーセンティケーターを有効にします。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
# config/packages/security.yaml
security:
    # ...

    firewalls:
        main:
            # ...
            x509:
                provider: your_user_provider

By default, Symfony extracts the email address from the DN in two different ways:

デフォルトでは、Symfony は 2 つの異なる方法で DN から電子メール アドレスを抽出します。
  1. First, it tries the SSL_CLIENT_S_DN_Email server parameter, which is exposed by Apache;
    まず、Apache によって公開されている SSL_CLIENT_S_DN_Email サーバー パラメータを試します。
  2. If it is not set (e.g. when using Nginx), it uses SSL_CLIENT_S_DN and matches the value following emailAddress=.
    設定されていない場合 (Nginx を使用している場合など)、SSL_CLIENT_S_DN を使用し、emailAddress= に続く値と一致します。

You can customize the name of both parameters under the x509 key. See the configuration reference for more details.

x509 キーの下にある両方のパラメーターの名前をカスタマイズできます。詳細については、構成リファレンスを参照してください。

Remote Users

Besides client certificate authentication, there are more web server modules that pre-authenticate a user (e.g. kerberos). The remote user authenticator provides a basic integration for these services.

クライアント証明書認証以外にも、ユーザーを事前認証する Web サーバーモジュールが他にもあります (例: kerberos)。リモート userauthenticator は、これらのサービスの基本的な統合を提供します。

These modules often expose the authenticated user in the REMOTE_USER environment variable. The remote user authenticator uses this value as the user identifier to load the corresponding user.

これらのモジュールは、多くの場合、認証されたユーザーを REMOTE_USER 環境変数で公開します。リモート・ユーザー・オーセンティケーターは、この値をユーザー ID として使用して、対応するユーザーをロードします。

Enable remote user authentication using the remote_user key:

remote_user キーを使用してリモート ユーザー認証を有効にします。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
# config/packages/security.yaml
security:
    firewalls:
        main:
            # ...
            remote_user:
                provider: your_user_provider

Tip

ヒント

You can customize the name of this server variable under the remote_user key. See the configuration reference for more details.

このサーバー変数の名前は、remote_user キーの下でカスタマイズできます。詳細については、構成リファレンスを参照してください。

Limiting Login Attempts

Symfony provides basic protection against brute force login attacks. You must enable this using the login_throttling setting:

symfony はブルート フォース ログイン攻撃に対する基本的な保護を提供します。login_throttling 設定を使用してこれを有効にする必要があります。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# config/packages/security.yaml
security:

    firewalls:
        # ...

        main:
            # ...

            # by default, the feature allows 5 login attempts per minute
            login_throttling: null

            # configure the maximum login attempts
            login_throttling:
                max_attempts: 3          # per minute ...
                # interval: '15 minutes' # ... or in a custom period

            # use a custom rate limiter via its service ID
            login_throttling:
                limiter: app.my_login_rate_limiter

Note

ノート

The value of the interval option must be a number followed by any of the units accepted by the PHP date relative formats (e.g. 3 seconds, 10 hours, 1 day, etc.)

interval オプションの値は、数値の後に PHP の日付相対形式で受け入れられる任意の単位 (例: 3 秒、10 時間、1 日など) を指定する必要があります。

Internally, Symfony uses the Rate Limiter component which by default uses Symfony's cache to store the previous login attempts. However, you can implement a custom storage.

内部的に、Symfony は Rate Limiter コンポーネントを使用します。これはデフォルトで Symfony のキャッシュを使用して以前のログイン試行を保存します。ただし、カスタム ストレージを実装できます。

Login attempts are limited on max_attempts (default: 5) failed requests for IP address + username and 5 * max_attempts failed requests for IP address. The second limit protects against an attacker using multiple usernames from bypassing the first limit, without disrupting normal users on big networks (such as offices).

ログイン試行は、max_attempts (デフォルト: 5) IP アドレス + ユーザー名の失敗した要求と 5 * max_attempts 失敗した IP アドレスの要求に制限されます。 2 番目の制限は、複数のユーザー名を使用する攻撃者が最初の制限をバイパスするのを防ぎ、大きなネットワーク (オフィスなど) の通常のユーザーを混乱させることはありません。

Tip

ヒント

Limiting the failed login attempts is only one basic protection against brute force attacks. The OWASP Brute Force Attacks guidelines mention several other protections that you should consider depending on the level of protection required.

失敗したログイン試行を制限することは、ブルート フォース攻撃に対する基本的な保護の 1 つにすぎません。 OWASP ブルート フォース攻撃のガイドラインには、必要な保護のレベルに応じて考慮すべきその他の保護がいくつか記載されています。

If you need a more complex limiting algorithm, create a class that implements RequestRateLimiterInterface (or use DefaultLoginRateLimiter) and set the limiter option to its service ID:

より複雑な制限アルゴリズムが必要な場合は、RequestRateLimiterInterface を実装する (または DefaultLoginRateLimiter を使用する) クラスを作成し、リミッター オプションをそのサービス ID に設定します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
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
# config/packages/security.yaml
framework:
    rate_limiter:
        # define 2 rate limiters (one for username+IP, the other for IP)
        username_ip_login:
            policy: token_bucket
            limit: 5
            rate: { interval: '5 minutes' }

        ip_login:
            policy: sliding_window
            limit: 50
            interval: '15 minutes'

services:
    # our custom login rate limiter
    app.login_rate_limiter:
        class: Symfony\Component\Security\Http\RateLimiter\DefaultLoginRateLimiter
        arguments:
            # globalFactory is the limiter for IP
            $globalFactory: '@limiter.ip_login'
            # localFactory is the limiter for username+IP
            $localFactory: '@limiter.username_ip_login'

security:
    firewalls:
        main:
            # use a custom rate limiter via its service ID
            login_throttling:
                limiter: app.login_rate_limiter

Login Programmatically

6.2

6.2

The Symfony\Bundle\SecurityBundle\Security class was introduced in Symfony 6.2. Prior to 6.2, it was called Symfony\Component\Security\Core\Security.

Symfony\Bundle\SecurityBundle\Securityclass は Symfony 6.2 で導入されました。 6.2 より前は、Symfony\Component\Security\Core\Security と呼ばれていました。

6.2

6.2

The login() method was introduced in Symfony 6.2.

login() メソッドは Symfony 6.2 で導入されました。

You can log in a user programmatically using the `login()` method of the Security helper:

Security ヘルパーの `login()` メソッドを使用して、プログラムでユーザーをログインできます。
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
// src/Controller/SecurityController.php
namespace App\Controller\SecurityController;

use App\Security\Authenticator\ExampleAuthenticator;
use Symfony\Bundle\SecurityBundle\Security;

class SecurityController
{
    public function someAction(Security $security): Response
    {
        // get the user to be authenticated
        $user = ...;

        // log the user in on the current firewall
        $security->login($user);

        // if the firewall has more than one authenticator, you must pass it explicitly
        // by using the name of built-in authenticators...
        $security->login($user, 'form_login');
        // ...or the service id of custom authenticators
        $security->login($user, ExampleAuthenticator::class);

        // you can also log in on a different firewall
        $security->login($user, 'form_login', 'other_firewall');

        // ... redirect the user to its account page for instance
    }
}

Logging Out

To enable logging out, activate the logout config parameter under your firewall:

ログアウトを有効にするには、ファイアウォールの下で logout 構成パラメーターを有効にします。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
11
12
# config/packages/security.yaml
security:
    # ...

    firewalls:
        main:
            # ...
            logout:
                path: app_logout

                # where to redirect after logout
                # target: app_any_route

Next, you need to create a route for this URL (but not a controller):

次に、この URL のルートを作成する必要があります (コントローラーは作成しません)。
  • Attributes
    属性
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// src/Controller/SecurityController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class SecurityController extends AbstractController
{
    #[Route('/logout', name: 'app_logout', methods: ['GET'])]
    public function logout()
    {
        // controller can be blank: it will never be called!
        throw new \Exception('Don\'t forget to activate logout in security.yaml');
    }
}

That's it! By sending a user to the app_logout route (i.e. to /logout) Symfony will un-authenticate the current user and redirect them.

それでおしまい!ユーザーを app_logout ルート (つまり /logout) に送信することで、Symfony は現在のユーザーの認証を解除し、リダイレクトします。

Logout programmatically

6.2

6.2

The Symfony\Bundle\SecurityBundle\Security class was introduced in Symfony 6.2. Prior to 6.2, it was called Symfony\Component\Security\Core\Security.

Symfony\Bundle\SecurityBundle\Securityclass は Symfony 6.2 で導入されました。 6.2 より前は、Symfony\Component\Security\Core\Security と呼ばれていました。

6.2

6.2

The logout() method was introduced in Symfony 6.2.

logout() メソッドは Symfony 6.2 で導入されました。

You can logout user programmatically using the logout() method of the Security helper:

Security ヘルパーの logout() メソッドを使用して、プログラムでユーザーをログアウトできます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// src/Controller/SecurityController.php
namespace App\Controller\SecurityController;

use Symfony\Bundle\SecurityBundle\Security;

class SecurityController
{
    public function someAction(Security $security): Response
    {
        // logout the user in on the current firewall
        $response = $security->logout();

        // you can also disable the csrf logout
        $response = $security->logout(false);

        // ... return $response (if set) or e.g. redirect to the homepage
    }
}

The user will be logout from the firewall of the request. If the request is not behind a firewall a \LogicException will be thrown.

ユーザーはリクエストのファイアウォールからログアウトされます。要求がファイアウォールの背後にない場合、\LogicException がスローされます。

Customizing Logout

In some cases you need to run extra logic upon logout (e.g. invalidate some tokens) or want to customize what happens after a logout. During logout, a LogoutEvent is dispatched. Register an event listener or subscriber to execute custom logic:

場合によっては、ログアウト時に追加のロジックを実行する必要がある (例: 一部のトークンを無効にする) か、ログアウト後の動作をカスタマイズする必要があります。ログアウト中に、LogoutEvent が送出されます。イベント リスナーまたはサブスクライバーを登録して、カスタム ロジックを実行します。
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
35
36
37
38
39
// src/EventListener/LogoutSubscriber.php
namespace App\EventListener;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Http\Event\LogoutEvent;

class LogoutSubscriber implements EventSubscriberInterface
{
    public function __construct(
        private UrlGeneratorInterface $urlGenerator
    ) {
    }

    public static function getSubscribedEvents(): array
    {
        return [LogoutEvent::class => 'onLogout'];
    }

    public function onLogout(LogoutEvent $event): void
    {
        // get the security token of the session that is about to be logged out
        $token = $event->getToken();

        // get the current request
        $request = $event->getRequest();

        // get the current response, if it is already set by another listener
        $response = $event->getResponse();

        // configure a custom logout response to the homepage
        $response = new RedirectResponse(
            $this->urlGenerator->generate('homepage'),
            RedirectResponse::HTTP_SEE_OTHER
        );
        $event->setResponse($response);
    }
}

Fetching the User Object

After authentication, the User object of the current user can be accessed via the getUser() shortcut in the base controller:

認証後、現在のユーザーの User オブジェクトには、ベース コントローラーの getUser() ショートカットを介してアクセスできます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class ProfileController extends AbstractController
{
    public function index(): Response
    {
        // usually you'll want to make sure the user is authenticated first,
        // see "Authorization" below
        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');

        // returns your User object, or null if the user is not authenticated
        // use inline documentation to tell your editor your exact User class
        /** @var \App\Entity\User $user */
        $user = $this->getUser();

        // Call whatever methods you've added to your User class
        // For example, if you added a getFirstName() method, you can use that.
        return new Response('Well hi there '.$user->getFirstName());
    }
}

Fetching the User from a Service

If you need to get the logged in user from a service, use the Security service:

ログインしているユーザーをサービスから取得する必要がある場合は、Security サービスを使用します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// src/Service/ExampleService.php
// ...

use Symfony\Bundle\SecurityBundle\Security;

class ExampleService
{
    private $security;

    public function __construct(Security $security)
    {
        // Avoid calling getUser() in the constructor: auth may not
        // be complete yet. Instead, store the entire Security object.
        $this->security = $security;
    }

    public function someMethod()
    {
        // returns User object or null if not authenticated
        $user = $this->security->getUser();

        // ...
    }
}

6.2

6.2

The Security class was introduced in Symfony 6.2. In previous Symfony versions this class was defined in Symfony\Component\Security\Core\Security.

Security クラスは Symfony 6.2 で導入されました。 Symfony の以前のバージョンでは、このクラスは Symfony\Component\Security\Core\Security で定義されていました。

Fetch the User in a Template

In a Twig Template the user object is available via the app.user variable thanks to the Twig global app variable:

Twig テンプレートでは、Twig グローバル アプリ変数のおかげで、ユーザー オブジェクトは app.user 変数を介して利用できます。
1
2
3
{% if is_granted('IS_AUTHENTICATED_FULLY') %}
    <p>Email: {{ app.user.email }}</p>
{% endif %}

Access Control (Authorization)

Users can now log in to your app using your login form. Great! Now, you need to learn how to deny access and work with the User object. This is called authorization, and its job is to decide if a user can access some resource (a URL, a model object, a method call, ...).

ユーザーは、ログイン フォームを使用してアプリにログインできるようになりました。すごい!ここで、アクセスを拒否し、ユーザー オブジェクトを操作する方法を学習する必要があります。これは承認と呼ばれ、ユーザーが何らかのリソース (URL、モデル オブジェクト、メソッド呼び出しなど) にアクセスできるかどうかを決定する役割があります。

The process of authorization has two different sides:

承認プロセスには、次の 2 つの側面があります。
  1. The user receives a specific role when logging in (e.g. ROLE_ADMIN).
    ユーザーはログイン時に特定の役割を受け取ります (例: ROLE_ADMIN)。
  2. You add code so that a resource (e.g. URL, controller) requires a specific "attribute" (e.g. a role like ROLE_ADMIN) in order to be accessed.
    リソース (例: URL、コントローラー) がアクセスされるために特定の「属性」 (例: ROLE_ADMIN のような役割) を必要とするようにコードを追加します。

Roles

When a user logs in, Symfony calls the getRoles() method on your User object to determine which roles this user has. In the User class that was generated earlier, the roles are an array that's stored in the database and every user is always given at least one role: ROLE_USER:

ユーザーがログインすると、Symfony は Userobject の getRoles() メソッドを呼び出して、このユーザーが持つロールを決定します。前に生成された User クラスでは、ロールはデータベースに格納された配列であり、すべてのユーザーには常に少なくとも 1 つのロールが与えられます: ROLE_USER:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// src/Entity/User.php

// ...
class User
{
    #[ORM\Column(type: 'json')]
    private $roles = [];

    // ...
    public function getRoles(): array
    {
        $roles = $this->roles;
        // guarantee every user at least has ROLE_USER
        $roles[] = 'ROLE_USER';

        return array_unique($roles);
    }
}

This is a nice default, but you can do whatever you want to determine which roles a user should have. The only rule is that every role must start with the ROLE_ prefix - otherwise, things won't work as expected. Other than that, a role is just a string and you can invent whatever you need (e.g. ROLE_PRODUCT_ADMIN).

これは適切なデフォルトですが、ユーザーが持つべきロールを決定するために必要なことは何でもできます。唯一のルールは、すべてのロールが ROLE_ プレフィックスで始まる必要があるということです。そうしないと、期待どおりに動作しません。それ以外は、役割は単なる文字列であり、必要なものは何でも作成できます (例: ROLE_PRODUCT_ADMIN)。

You'll use these roles next to grant access to specific sections of your site.

次に、これらの役割を使用して、サイトの特定のセクションへのアクセスを許可します。

Hierarchical Roles

Instead of giving many roles to each user, you can define role inheritance rules by creating a role hierarchy:

各ユーザーに多くのロールを付与する代わりに、ロール階層を作成してロール継承ルールを定義できます。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
# config/packages/security.yaml
security:
    # ...

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

Users with the ROLE_ADMIN role will also have the ROLE_USER role. Users with ROLE_SUPER_ADMIN, will automatically have ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH and ROLE_USER (inherited from ROLE_ADMIN).

ROLE_ADMIN ロールを持つユーザーは、ROLE_USER ロールも持ちます。ROLE_SUPER_ADMIN を持つユーザーは、ROLE_ADMIN、ROLE_ALLOWED_TO_SWITCH、および ROLE_USER (ROLE_ADMIN から継承) を自動的に持ちます。

Caution

注意

For role hierarchy to work, do not use $user->getRoles() manually. For example, in a controller extending from the base controller:

ロール階層が機能するためには、$user->getRoles() を手動で使用しないでください。たとえば、ベース コントローラーから拡張されたコントローラーでは次のようになります。
1
2
3
4
5
6
// BAD - $user->getRoles() will not know about the role hierarchy
$hasAccess = in_array('ROLE_ADMIN', $user->getRoles());

// GOOD - use of the normal security methods
$hasAccess = $this->isGranted('ROLE_ADMIN');
$this->denyAccessUnlessGranted('ROLE_ADMIN');

Note

ノート

The role_hierarchy values are static - you can't, for example, store the role hierarchy in a database. If you need that, create a custom security voter that looks for the user roles in the database.

role_hierarchy の値は静的です。たとえば、ロール階層をデータベースに格納することはできません。必要な場合は、データベース内のユーザー ロールを検索するカスタム セキュリティ ボーターを作成します。

Add Code to Deny Access

There are two ways to deny access to something:

何かへのアクセスを拒否するには、次の 2 つの方法があります。
  1. access_control in security.yaml allows you to protect URL patterns (e.g. /admin/*). Simpler, but less flexible;
    security.yaml の access_control を使用すると、URL パターン (/admin/* など) を保護できます。より単純ですが、柔軟性が低くなります。
  2. in your controller (or other code).
    コントローラー(または他のコード)で。

Securing URL patterns (access_control)

The most basic way to secure part of your app is to secure an entire URL pattern in security.yaml. For example, to require ROLE_ADMIN for all URLs that start with /admin, you can:

アプリの一部を保護する最も基本的な方法は、security.yaml で URL パターン全体を保護することです。たとえば、/admin で始まるすべての URL に ROLE_ADMIN を要求するには、次のようにします。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# config/packages/security.yaml
security:
    # ...

    firewalls:
        # ...
        main:
            # ...

    access_control:
        # require ROLE_ADMIN for /admin*
        - { path: '^/admin', roles: ROLE_ADMIN }

        # or require ROLE_ADMIN or IS_AUTHENTICATED_FULLY for /admin*
        - { path: '^/admin', roles: [IS_AUTHENTICATED_FULLY, ROLE_ADMIN] }

        # the 'path' value can be any valid regular expression
        # (this one will match URLs like /api/post/7298 and /api/comment/528491)
        - { path: ^/api/(post|comment)/\d+$, roles: ROLE_USER }

You can define as many URL patterns as you need - each is a regular expression. BUT, only one will be matched per request: Symfony starts at the top of the list and stops when it finds the first match:

必要な数の URL パターンを定義できます - それぞれが正規表現です。しかし、リクエストごとに 1 つだけが一致します: Symfony はリストの先頭から開始し、最初の一致が見つかったときに停止します:
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
# config/packages/security.yaml
security:
    # ...

    access_control:
        # matches /admin/users/*
        - { path: '^/admin/users', roles: ROLE_SUPER_ADMIN }

        # matches /admin/* except for anything matching the above rule
        - { path: '^/admin', roles: ROLE_ADMIN }

Prepending the path with ^ means that only URLs beginning with the pattern are matched. For example, a path of /admin (without the ^) would match /admin/foo but would also match URLs like /foo/admin.

パスの前に ^ を追加すると、そのパターンで始まる URL のみが一致することを意味します。たとえば、/admin のパス (^ なし) は /admin/foo に一致しますが、/foo/admin などの URL にも一致します。

Each access_control can also match on IP address, hostname and HTTP methods. It can also be used to redirect a user to the https version of a URL pattern. For more complex needs, you can also use a service implementing RequestMatcherInterface.

各 access_control は、IP アドレス、ホスト名、および HTTP メソッドでも照合できます。ユーザーを URL パターンの https バージョンにリダイレクトするためにも使用できます。より複雑なニーズについては、RequestMatcherInterface を実装するサービスを使用することもできます。

See How Does the Security access_control Work?.

セキュリティ access_control の仕組みを参照してください。

Securing Controllers and other Code

You can deny access from inside a controller:

コントローラー内からのアクセスを拒否できます。
1
2
3
4
5
6
7
8
9
10
// src/Controller/AdminController.php
// ...

public function adminDashboard(): Response
{
    $this->denyAccessUnlessGranted('ROLE_ADMIN');

    // or add an optional message - seen by developers
    $this->denyAccessUnlessGranted('ROLE_ADMIN', null, 'User tried to access a page without having ROLE_ADMIN');
}

That's it! If access is not granted, a special AccessDeniedException is thrown and no more code in your controller is called. Then, one of two things will happen:

それでおしまい!アクセスが許可されていない場合、specialAccessDeniedException がスローされ、コントローラー内のコードは呼び出されません。次に、次の 2 つのいずれかが発生します。
  1. If the user isn't logged in yet, they will be asked to log in (e.g. redirected to the login page).
    ユーザーがまだログインしていない場合は、ログインするよう求められます (例: ログイン ページにリダイレクトされます)。
  2. If the user is logged in, but does not have the ROLE_ADMIN role, they'll be shown the 403 access denied page (which you can customize).
    ユーザーがログインしているが、ROLE_ADMIN ロールを持っていない場合、403 アクセス拒否ページが表示されます (カスタマイズ可能)。

Another way to secure one or more controller actions is to use an attribute. In the following example, all controller actions will require the ROLE_ADMIN permission, except for adminDashboard(), which will require the ROLE_SUPER_ADMIN permission:

1 つまたは複数のコントローラー アクションを保護するもう 1 つの方法は、属性を使用することです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// src/Controller/AdminController.php
// ...

use Symfony\Component\Security\Http\Attribute\IsGranted;

#[IsGranted('ROLE_ADMIN')]
class AdminController extends AbstractController
{
    #[IsGranted('ROLE_SUPER_ADMIN')]
    public function adminDashboard(): Response
    {
        // ...
    }
}

6.2

6.2

The #[IsGranted()] attribute was introduced in Symfony 6.2.

#[IsGranted()] 属性は Symfony 6.2 で導入されました。

Access Control in Templates

If you want to check if the current user has a certain role, you can use the built-in is_granted() helper function in any Twig template:

現在のユーザーが特定の役割を持っているかどうかを確認したい場合は、任意の Twig テンプレートで組み込みの is_granted() ヘルパー関数を使用できます。
1
2
3
{% if is_granted('ROLE_ADMIN') %}
    <a href="...">Delete</a>
{% endif %}

Securing other Services

You can check access anywhere in your code by injecting the Security service. For example, suppose you have a SalesReportManager service and you want to include extra details only for users that have a ROLE_SALES_ADMIN role:

Securityservice を挿入することにより、コード内の任意の場所でアクセスをチェックできます。たとえば、SalesReportManager サービスがあり、ROLE_SALES_ADMIN ロールを持つユーザーにのみ追加の詳細を含めたいとします。
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
// src/SalesReport/SalesReportManager.php

  // ...
  use Symfony\Component\Security\Core\Exception\AccessDeniedException;
+ use Symfony\Bundle\SecurityBundle\Security;

  class SalesReportManager
  {
+     private $security;

+     public function __construct(Security $security)
+     {
+         $this->security = $security;
+     }

      public function generateReport()
      {
          $salesData = [];

+         if ($this->security->isGranted('ROLE_SALES_ADMIN')) {
+             $salesData['top_secret_numbers'] = rand();
+         }

          // ...
      }

      // ...
  }

If you're using the default services.yaml configuration, Symfony will automatically pass the security.helper to your service thanks to autowiring and the Security type-hint.

デフォルトの services.yaml 設定を使用している場合、Symfony は autowireing と Security type-hint のおかげで、自動的に security.helper をサービスに渡します。

You can also use a lower-level AuthorizationCheckerInterface service. It does the same thing as Security, but allows you to type-hint a more-specific interface.

下位レベルの AuthorizationCheckerInterface サービスを使用することもできます。これは Security と同じことを行いますが、より特定のインターフェースにタイプヒントを与えることができます。

Allowing Unsecured Access (i.e. Anonymous Users)

When a visitor isn't yet logged in to your website, they are treated as "unauthenticated" and don't have any roles. This will block them from visiting your pages if you defined an access_control rule.

訪問者がまだ Web サイトにログインしていない場合、その訪問者は「認証されていない」ものとして扱われ、何の役割も持っていません。 access_control ルールを定義した場合、これにより、ページへのアクセスがブロックされます。

In the access_control configuration, you can use the PUBLIC_ACCESS security attribute to exclude some routes for unauthenticated access (e.g. the login page):

access_control 構成では、PUBLIC_ACCESSsecurity 属性を使用して、認証されていないアクセス (ログイン ページなど) の一部のルートを除外できます。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
# config/packages/security.yaml
security:

    # ...
    access_control:
        # allow unauthenticated users to access the login form
        - { path: ^/admin/login, roles: PUBLIC_ACCESS }

        # but require authentication for all other admin routes
        - { path: ^/admin, roles: ROLE_ADMIN }

Granting Anonymous Users Access in a Custom Voter

If you're using a custom voter, you can allow anonymous users access by checking if there is no user set on the token:

カスタムボーターを使用している場合は、トークンにユーザーが設定されていないかどうかを確認することで、匿名ユーザーのアクセスを許可できます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// src/Security/PostVoter.php
namespace App\Security;

// ...
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\User\UserInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;

class PostVoter extends Voter
{
    // ...

    protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
    {
        // ...

        if (!$token->getUser() instanceof UserInterface) {
            // the user is not authenticated, e.g. only allow them to
            // see public posts
            return $subject->isPublic();
        }
    }
}

Setting Individual User Permissions

Most applications require more specific access rules. For instance, a user should be able to only edit their own comments on a blog. Voters allow you to write whatever business logic you need to determine access. Using these voters is similar to the role-based access checks implemented in the previous chapters. Read How to Use Voters to Check User Permissions to learn how to implement your own voter.

ほとんどのアプリケーションでは、より具体的なアクセス ルールが必要です。たとえば、ユーザーはブログの自分のコメントのみを編集できる必要があります。投票者を使用すると、アクセスを決定するために必要なビジネス ロジックを記述できます。これらのボーターの使用は、前の章で実装された役割ベースのアクセス チェックに似ています。投票者を使用してユーザー権限を確認する方法を読んで、独自の投票者を実装する方法を学んでください。

Checking to see if a User is Logged In (IS_AUTHENTICATED_FULLY)

If you only want to check if a user is logged in (you don't care about roles), you have the following two options.

ユーザーがログインしているかどうかのみを確認したい場合 (ロールは気にしない場合)、次の 2 つのオプションがあります。

Firstly, if you've given every user ROLE_USER, you can check for that role.

まず、すべてのユーザーに ROLE_USER を付与した場合、そのロールを確認できます。

Secondly, you can use a special "attribute" in place of a role:

次に、ロールの代わりに特別な「属性」を使用できます。
1
2
3
4
5
6
7
8
// ...

public function adminDashboard(): Response
{
    $this->denyAccessUnlessGranted('IS_AUTHENTICATED');

    // ...
}

You can use IS_AUTHENTICATED anywhere roles are used: like access_control or in Twig.

IS_AUTHENTICATED は、access_control や Twig など、ロールが使用されている場所ならどこでも使用できます。

IS_AUTHENTICATED isn't a role, but it kind of acts like one, and every user that has logged in will have this. Actually, there are some special attributes like this:

IS_AUTHENTICATED は役割ではありませんが、役割のように機能し、ログインしたすべてのユーザーがこれを持ちます。実際には、次のような特別な属性がいくつかあります。
  • IS_AUTHENTICATED_REMEMBERED: all logged in users have this, even if they are logged in because of a "remember me cookie". Even if you don't use the remember me functionality, you can use this to check if the user is logged in.
    IS_AUTHENTICATED_REMEMBERED: ログインしているすべてのユーザーは、「remember me cookie」のためにログインしている場合でも、これを持っています。記憶機能を使用しない場合でも、これを使用してユーザーがログインしているかどうかを確認できます。
  • IS_AUTHENTICATED_FULLY: This is similar to IS_AUTHENTICATED_REMEMBERED, but stronger. Users who are logged in only because of a "remember me cookie" will have IS_AUTHENTICATED_REMEMBERED but will not have IS_AUTHENTICATED_FULLY.
    IS_AUTHENTICATED_FULLY: これは IS_AUTHENTICATED_REMEMBERED に似ていますが、より強力です。 「remember me cookie」のためだけにログインしているユーザーは、IS_AUTHENTICATED_REMEMBERED を持つことになりますが、IS_AUTHENTICATED_FULLY を持つことはありません。
  • IS_REMEMBERED: Only users authenticated using the remember me functionality, (i.e. a remember-me cookie).
    IS_REMEMBERED:remember me 機能 (つまり、remember-me cookie) を使用して認証されたユーザーのみ。
  • IS_IMPERSONATOR: When the current user is impersonating another user in this session, this attribute will match.
    IS_IMPERSONATOR: 現在のユーザーがこのセッションで別のユーザーになりすましている場合、この属性は一致します。

Understanding how Users are Refreshed from the Session

At the end of every request (unless your firewall is stateless), your User object is serialized to the session. At the beginning of the next request, it's deserialized and then passed to your user provider to "refresh" it (e.g. Doctrine queries for a fresh user).

すべてのリクエストの最後に (ファイアウォールがステートレスでない限り)、yourUser オブジェクトはセッションにシリアル化されます。 nextrequest の開始時に、デシリアライズされ、ユーザー プロバイダーに渡されて「更新」されます (たとえば、新しいユーザーに対する Doctrine クエリ)。

Then, the two User objects (the original from the session and the refreshed User object) are "compared" to see if they are "equal". By default, the core AbstractToken class compares the return values of the getPassword(), getSalt() and getUserIdentifier() methods. If any of these are different, your user will be logged out. This is a security measure to make sure that malicious users can be de-authenticated if core user data changes.

次に、2 つのユーザー オブジェクト (セッションの元のオブジェクトと更新されたユーザー オブジェクト) が「比較」され、「等しい」かどうかが確認されます。デフォルトでは、coreAbstractToken クラスは getPassword()、getSalt()、および getUserIdentifier() メソッドの戻り値を比較します。これらのいずれかが異なる場合、ユーザーはログアウトされます。これは、コア ユーザー データが変更された場合に、悪意のあるユーザーの認証を確実に解除できるようにするためのセキュリティ対策です。

However, in some cases, this process can cause unexpected authentication problems. If you're having problems authenticating, it could be that you are authenticating successfully, but you immediately lose authentication after the first redirect.

ただし、場合によっては、このプロセスによって予期しない認証の問題が発生する可能性があります。認証に問題がある場合は、認証に成功していても、最初のリダイレクト後にすぐに認証が失われる可能性があります。

In that case, review the serialization logic (e.g. the __serialize() or serialize() methods) on you user class (if you have any) to make sure that all the fields necessary are serialized and also exclude all the fields not necessary to be serialized (e.g. Doctrine relations).

その場合、ユーザー クラス (存在する場合) のシリアル化ロジック (__serialize() またはserialize() メソッドなど) を見直して、必要なすべてのフィールドがシリアル化されていることを確認し、シリアル化する必要のないすべてのフィールドを除外します (例:教義関係)。

Comparing Users Manually with EquatableInterface

Or, if you need more control over the "compare users" process, make your User class implement EquatableInterface. Then, your isEqualTo() method will be called when comparing users instead of the core logic.

または、「ユーザーの比較」プロセスをさらに制御する必要がある場合は、User クラスに EquatableInterface を実装させます。次に、コア ロジックの代わりにユーザーを比較するときに isEqualTo() メソッドが呼び出されます。

Security Events

During the authentication process, multiple events are dispatched that allow you to hook into the process or customize the response sent back to the user. You can do this by creating an event listener or subscriber for these events.

認証プロセス中に、複数のイベントがディスパッチされ、プロセスにフックしたり、ユーザーに返される応答をカスタマイズしたりできます。これを行うには、これらのイベントのイベント リスナーまたはサブスクライバーを作成します。

Tip

ヒント

Every Security firewall has its own event dispatcher (security.event_dispatcher.FIREWALLNAME). Events are dispatched on both the global and the firewall-specific dispatcher. You can register on the firewall dispatcher if you want your listener to only be called for a specific firewall. For instance, if you have an api and main firewall, use this configuration to register only on the logout event in the main firewall:

すべてのセキュリティ ファイアウォールには、独自のイベント ディスパッチャー (security.event_dispatcher.FIREWALLNAME) があります。イベントは、グローバル ディスパッチャとファイアウォール固有のディスパッチャの両方でディスパッチされます。リスナーを特定のファイアウォールに対してのみ呼び出したい場合は、ファイアウォール ディスパッチャに登録できます。たとえば、API とメイン ファイアウォールがある場合は、次の構成を使用して、メイン ファイアウォールのログアウト イベントのみに登録します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
# config/services.yaml
services:
    # ...

    App\EventListener\LogoutSubscriber:
        tags:
            - name: kernel.event_subscriber
              dispatcher: security.event_dispatcher.main

Authentication Events

CheckPassportEvent
Dispatched after the authenticator created the security passport. Listeners of this event do the actual authentication checks (like checking the passport, validating the CSRF token, etc.)
オーセンティケータがセキュリティ パスポートを作成した後に送出されます。このイベントのリスナーは、実際の認証チェックを行います (パスポートのチェック、CSRF トークンの検証など)。
AuthenticationTokenCreatedEvent
Dispatched after the passport was validated and the authenticator created the security token (and user). This can be used in advanced use-cases where you need to modify the created token (e.g. for multi factor authentication).
パスポートが検証され、オーセンティケータがセキュリティ トークン (およびユーザー) を作成した後にディスパッチされます。これは、作成されたトークンを変更する必要がある高度なユースケース (多要素認証など) で使用できます。
AuthenticationSuccessEvent
Dispatched when authentication is nearing success. This is the last event that can make an authentication fail by throwing an AuthenticationException.
認証が成功に近づいたときに送出されます。これは、AuthenticationException をスローして認証を失敗させる最後のイベントです。
LoginSuccessEvent
Dispatched after authentication was fully successful. Listeners to this event can modify the response sent back to the user.
認証が完全に成功した後に送出されます。このイベントのリスナーは、ユーザーに返される応答を変更できます。
LoginFailureEvent
Dispatched after an AuthenticationException was thrown during authentication. Listeners to this event can modify the error response sent back to the user.
認証中に AuthenticationException がスローされた後に送出されます。このイベントのリスナーは、ユーザーに返されるエラー応答を変更できます。

Other Events

LogoutEvent
Dispatched just before a user logs out of your application. See Security.
ユーザーがアプリケーションからログアウトする直前にディスパッチされます。セキュリティを参照してください。
TokenDeauthenticatedEvent
Dispatched when a user is deauthenticated, for instance because the password was changed. See Security.
パスワードが変更されたなどの理由で、ユーザーの認証が解除されたときに送出されます。セキュリティを参照してください。
SwitchUserEvent
Dispatched after impersonation is completed. See How to Impersonate a User.
なりすまし完了後に発送。ユーザーを偽装する方法を参照してください。

Frequently Asked Questions

Can I have Multiple Firewalls?
Yes! But it's usually not necessary. Each firewall is like a separate security system, being authenticated in one firewall doesn't make you authenticated in another one. One firewall can have multiple diverse ways of allowing authentication (e.g. form login, API key authentication and LDAP).
はい!しかし、通常は必要ありません。各ファイアウォールは個別のセキュリティ システムのようなもので、1 つのファイアウォールで認証されても、別のファイアウォールで認証されるわけではありません。 1 つのファイアウォールで、認証を許可するさまざまな方法を複数持つことができます (フォーム ログイン、API キー認証、LDAP など)。
Can I Share Authentication Between Firewalls?
Yes, but only with some configuration. If you're using multiple firewalls and you authenticate against one firewall, you will not be authenticated against any other firewalls automatically. Different firewalls are like different security systems. To do this you have to explicitly specify the same Security Configuration Reference (SecurityBundle) for different firewalls. However, one main firewall is usually sufficient for the needs of most applications.
はい。ただし、一部の構成のみです。複数のファイアウォールを使用していて、1 つのファイアウォールに対して認証する場合、他のファイアウォールに対して自動的に認証されることはありません。異なるファイアウォールは、異なるセキュリティ システムのようなものです。これを行うには、異なるファイアウォールに対して同じセキュリティ構成リファレンス (SecurityBundle) を明示的に指定する必要があります。ただし、ほとんどのアプリケーションのニーズには通常、1 つのメイン ファイアウォールで十分です。
Security doesn't seem to work on my Error Pages
As routing is done before security, 404 error pages are not covered by any firewall. This means you can't check for security or even access the user object on these pages. See How to Customize Error Pages for more details.
セキュリティの前にルーティングが行われるため、404 エラー ページはファイアウォールによってカバーされません。これは、セキュリティをチェックしたり、これらのページのユーザー オブジェクトにアクセスしたりすることさえできないことを意味します。詳細については、エラー ページをカスタマイズする方法を参照してください。
My Authentication Doesn't Seem to Work: No Errors, but I'm Never Logged In
Sometimes authentication may be successful, but after redirecting, you're logged out immediately due to a problem loading the User from the session. To see if this is an issue, check your log file (var/log/dev.log) for the log message:
認証が成功する場合がありますが、リダイレクト後、セッションからユーザーをロードするときに問題が発生したため、すぐにログアウトされます。これが問題であるかどうかを確認するには、ログ ファイル (var/log/dev.log) でログ メッセージを確認してください。 :
Cannot refresh token because user has changed
If you see this, there are two possible causes. First, there may be a problem loading your User from the session. See Security. Second, if certain user information was changed in the database since the last page refresh, Symfony will purposely log out the user for security reasons.
これが表示された場合、考えられる原因は 2 つあります。まず、セッションからのユーザーのロードに問題がある可能性があります。セキュリティを参照してください。第 2 に、最後のページ更新以降にデータベースで特定のユーザー情報が変更された場合、Symfony はセキュリティ上の理由から意図的にユーザーをログアウトします。

Learn More

Authentication (Identifying/Logging in the User)

Authorization (Denying Access)