Нововведения Symfony 8.2: режим sudo, ускорение Messenger и сопровождение PGP/MIME

7 мин
Нововведения Symfony 8.2: режим sudo, ускорение Messenger и сопровождение PGP/MIME

В версии 8.2 появится несколько важных нововведений: встроенный режим sudo с атрибутами IS_AUTHENTICATED_RECENTLY и IS_AUTHENTICATED_VERY_RECENTLY, которые требуют повторной аутентификации перед выполнением конфиденциальных действий, функция --concurrency для параллельной обработки сообщений в Messenger, ускоряющая работу до 7,5 раза, параметр prefetch_count для AMQP и сопровождение PGP/MIME в компоненте Mime, позволяющая подписывать и шифровать письма с помощью ключей OpenPGP. Выпуск запланирован на ноябрь 2026 года.

Встроенный режим sudo

Встроенный режим sudo позволяет приложениям требовать повторный вход в систему перед выполнением важных действий, в частности изменения адреса электронной почты или удаления учетной записи.

Флаг IS_AUTHENTICATED_FULLY — самая строгая тест статуса авторизации в Symfony, однако указывает она только на то, как была запущена сессия. Следовательно, скажем, пользователь, вошедший в систему восемь часов назад и оставивший портативный компьютер разблокированным, по-прежнему считается полностью аутентифицированным. В теории любой может совершить оплату с его аккаунта или удалить учетную запись. Сервисы вроде GitHub решают эту проблему с помощью режима sudo, запрашивающего учетные информация заново перед выполнением потенциально опасных действий. В Symfony 8.2 эта функция будет добавлена на уровне ядра.

Появятся два атрибута безопасности, расширяющих возможности IS_AUTHENTICATED_FULLY: IS_AUTHENTICATED_RECENTLY (учетные информация введены на протяжении последних двух часов) и IS_AUTHENTICATED_VERY_RECENTLY (на протяжении последних пяти минут). Их можно использовать везде, где применяются другие атрибуты серии IS_AUTHENTICATED_*, в том числе access_control и шаблоны Twig. 

Например, для изменения адреса электронной почты можно инсталлировать требование о недавнем входе в систему, а для удаления учетной записи — о входе, совершенном совсем недавно:

// src/Controller/AccountController.php
use Symfony\Component\Security\Http\Attribute\IsGranted;
// ... #[IsGranted('IS_AUTHENTICATED_RECENTLY')]
public function changeEmail(): Response
{ // ...
} #[IsGranted('IS_AUTHENTICATED_VERY_RECENTLY')]
public function deleteAccount(): Response
{ // ...
}

В security expressions равным образом появятся функции is_recently_authenticated() и is_very_recently_authenticated(). Пользователи, авторизованные только через cookie «запомнить меня», не пройдут эти проверки, поскольку такой cookie может быть использован любым лицом, имеющим доступ к браузеру. Временные ограничения настраиваются в security.yaml в секундах:

# config/packages/security.yaml
security: recent_authentication_lifetime: 3_600 # default: 7_200 very_recent_authentication_lifetime: 60 # default: 300

Если атрибуты отсутствуют, пользователи по умолчанию зарабатывают ошибку 403. Новый интерфейс ReAuthenticationEntryPointInterface даёт возможность перенаправить пользователей для повторной аутентификации вместо отображения ошибки. Для этого необходимо сначала создать сервис, реализующий свежий интерфейс:

// src/Security/ConfirmPasswordEntryPoint.php
namespace App\Security; use Symfony\Component\Security\Http\EntryPoint\ReAuthenticationEntryPointInterface;
// ... final class ConfirmPasswordEntryPoint implements ReAuthenticationEntryPointInterface
{ public function __construct( private UrlGeneratorInterface $urlGenerator, ) { } public function startReAuthentication(Request $request, TokenInterface $token): Response { // this page displays a password form that submits to the form_login check_path return new RedirectResponse($this->urlGenerator->generate('app_confirm_password')); }
}

Затем настроить брандмауэр для работы с ним с помощью нового параметра re_authentication_entry_point:

// config/packages/security.php
namespace Symfony\Component\DependencyInjection\Loader\Configurator; use App\Security\ConfirmPasswordEntryPoint; return App::config([ 'security' => [ 'firewalls' => [ 'main' => [ 'form_login' => [ // ... ], 're_authentication_entry_point' => ConfirmPasswordEntryPoint::class, ], ], ],
]);

Если точка входа брандмауэра уже реализует этот интерфейс, параметр можно пропустить. Свежий механизм входа через OpenID Connect делает это автоматически: он перенаправляет пользователей обратно к провайдеру с параметром prompt=login, для повторного ввода учетных данных.

Symfony равным образом использует свойство auth_time в ID-токене для проверки того, когда пользователь фактически прошел аутентификацию. Таким образом, автоматический вход через старую сессию у провайдера не считается новым входом в систему.

VDS-серверы от 200 ₽/месяц

Семь готовых конфигураций, KVM-виртуализация, NVMe SSD и техническая поддержка 24/7.

Запустить в пару кликов →

Ускорение рабочих процессов Messenger

Вводится также новая опция --concurrency для рабочих процессов Messenger. Она даёт возможность одному рабочему процессу параллельно обрабатывать несколько сообщений с помощью библиотеки amphp/parallel или расширения PHP parallel. 

В тестах производительности с сообщениями, обработка каждого из которых занимает 20 мс, параметр --concurrency=8 представил эффективность в 7,5 раз выше, чем у одного рабочего процесса. 

Рабочий процесс по-прежнему самостоятельно извлекает сообщения, поэтому ему требуется только одно соединение с транспортным протприблизительном, независимо от того, сколько сообщений обрабатывается параллельно. Удаление составляют пакетные обработчики: все сообщения в пакете должны обрабатываться одним и тем же дочерним процессом, следовательно параметр --concurrency не ускоряет их обработку, и для параллельной обработки пакетов следует продолжать запускать несколько рабочих процессов.

Транспортный протокол AMQP запрашивает у брокера по одному сообщению за раз, что требует одного цикла обмена данными по сети на каждое сообщение. RabbitMQ полагает это наименее эффективным способом получения сообщений. Свежий параметр prefetch_count регистрирует реального потребителя для каждой очереди и даёт возможность брокеру заранее отправлять ему сообщения.

В тестах относительно локальным брокером скорость обработки сообщений была в 13–18 раз выше. Зарегистрированные потребители равным образом отображаются в интерфейсе управления RabbitMQ. Значение prefetch_count должно быть больше размера извлечения рабочего процесса, который по умолчанию равен значению параметра --concurrency.

Предварительная загрузка по умолчанию отключена, поскольку она изменяет метод обработки сообщений. Теперь брокер определяет порядок между очередями, а любые предварительно загруженные сообщения, все еще ожидающие обработки, повторно доставляются при остановке рабочего процесса.

Отправка отложенных сообщений также становится менее затратной. В AMQP нет встроенных задержек, следовательно Symfony создает очередь задержки для каждого отдельного значения задержки. Стратегия повторных попыток по умолчанию добавляет колебания к этим задержкам, что приводит к появлению более тысячи различных значений, и при каждой повторной попытке обычно объявляется и привязывается новая очередь.

Задержки округляются в большую сторону (в частности, 5234 мс становится 5300 мс). Это на несколько порядков сокращает количество очередей задержек и гарантирует, что сообщения будут отправлены не раньше заданной задержки и не позднее, чем на 10% позже нее. Свежий параметр delay[granularity] даёт возможность округлять задержки до фиксированного числа миллисекунд или отключить округление, установив его равным 1:

# .env
MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages?delay[granularity]=1000

Новое опциональное промежуточное ПО для ведения журналов фиксирует время обработки и объем используемой памяти для каждого сообщения. Его стоит активировать на тех шинах, которые вы хотите отслеживать:

// config/packages/messenger.php
namespace Symfony\Component\DependencyInjection\Loader\Configurator; return App::config([ 'framework' => [ 'messenger' => [ 'buses' => [ 'messenger.bus.default' => [ 'middleware' => ['logging'], ], ], ], ],
]);

Оно отслеживает все, что запускается после него в стеке, и записывает сообщения в канал мессенджера с контекстными ключами class, duration_ms и memory_usage (в байтах). Это позволяет разрабатывать на их основе информационные панели и настраивать оповещения.

Электронные письма, подписанные и зашифрованные с помощью PGP/MIME

Symfony поддерживает подпись и шифрование электронных писем по стандарту S/MIME начиная с версии Symfony 4.4, а в Symfony 7.3 была добавлена функция глобальной подписи и шифрования. Это даёт возможность настроить эту функцию один раз для всех писем. Тем не менее S/MIME использует сертификаты X.509, выдаваемые центрами сертификации, в то время как многие пользователи вместо них используют ключи OpenPGP. В Symfony 8.2 добавится сопровождение этих ключей, а также будут улучшены существующие функции S/MIME.

В компонент Mime добавят поддержку PGP/MIME (RFC 3156). Она работает аналогично функции S/MIME: подписант добавляет к сообщению отдельную подпись, а шифровальщик шифрует его с помощью открытых ключей получателей:

use Symfony\Component\Mime\Crypto\PgpEncrypter;
use Symfony\Component\Mime\Crypto\PgpSigner; $signer = new PgpSigner('/path/to/secret.asc', '/path/to/public.asc', $passphrase);
$signedEmail = $signer->sign($email); $encrypter = new PgpEncrypter();
$encryptedEmail = $encrypter->encrypt($signedEmail, [ 'alice@example.com' => '/path/to/alice.asc',
]);

В приложениях полного цикла это настраивается один раз в настройках Mailer:

# config/packages/mailer.yaml
framework: mailer: pgp_signer: secret_key: '%kernel.project_dir%/config/keys/private.asc' passphrase: '%env(PGP_PASSPHRASE)%' pgp_encrypter: keys: 'alice@example.com': '%kernel.project_dir%/config/keys/alice.asc' # or use a service implementing PgpPublicKeyRepositoryInterface # repository: App\Mailer\PublicKeyRepository on_missing_key: 'fail' # fail | encrypt | skip 

Затем в письма, которые нужно защитить, добавляются заголовки X-Pgp-Sign и/или X-Pgp-Encrypt. Symfony подписывает и шифрует их после отображения содержимого (следовательно это работает с TemplatedEmail) и всегда подписывает перед шифрованием:

$email->getHeaders()->addTextHeader('X-Pgp-Sign', 'true');
$email->getHeaders()->addTextHeader('X-Pgp-Encrypt', 'true');

Функция использует бинарный файл gpg через компонент Process, следовательно не требует никаких расширений PHP. Шифруется только тело сообщения, заголовки остаются видимыми. Опция находится в экспериментальной стадии, поэтому ее api может изменяться в незначительных версиях.

В процессе разработки поддержки PGP/MIME некоторые идеи были применены и к существующим функциям S/MIME. Ранее, если хотя бы у одного получателя не было сертификата S/MIME, сообщение отправлялось всем в незашифрованном виде. В Symfony 8.2 добавится параметр on_missing_certificate с теми же значениями, что и у PGP (fail, encrypt и skip). Сертификаты равным образом можно указывать непосредственно в конфигурации:

# config/packages/mailer.yaml
framework: mailer: smime_encrypter: certificates: 'alice@example.com': '%kernel.project_dir%/config/certificates/alice.crt' on_missing_certificate: 'fail'

Для обеспечения обратной совместимости значением по умолчанию остается send_unencrypted, тем не менее оно признано устаревшим, и в Symfony 9.0 в этом случае будет сгенерировано исключение. Поведение можно переопределить для каждого сообщения с помощью заголовка X-SMime-Encrypt (в частности, X-SMime-Encrypt: skip).

Читают сейчас

1 час назад

UserGate назначил вице-президентом по HR экс‑топ‑менеджера Cisco Елену Щедрову

UserGate, ведущий российский разработчик решений в области кибербезопасности и архитектор сетевого доверия, объявил о назначении Елены Щедровой на должность вице‑президента по HR. Она будет отвечать з

1 час назад

UserGate и Новгородский филиал РАНХиГС подписали партнёрское соглашение

UserGate, ведущий российский разработчик решений в области кибербезопасности и архитектор сетевого доверия, и Новгородский филиал Российской академии народного хозяйства и государственной службы при П

Вышел Tails 7.14

1 час назад

Вышел Tails 7.14

В конце сентября 2026 года состоялся выпуск специализированного дистрибутива Tails 7.14, ориентированного на конфиденциальность, основанного на пакетной базе Debian 13 (ядре Linux 6.12 LTS), поставляе

1 час назад

Аналитики UserGate на Cекретной сессии uFactor 2026 представили информация о переходе рынка ИБ на внешние и гибридные SOC

UserGate, российский разработчик решений в области информационной безопасности и архитектор сетевого доверия, поделился аналитикой услуг и сервисов рынка информационной безопасности в рамках Секретной

Записи Fintech Product Meetup: как ИИ применяют в переводах, поддержке и аналитике

1 час назад

Записи Fintech Product Meetup: как ИИ применяют в переводах, поддержке и аналитике

Мы провели Fintech Product Meetup — бесплатный встреча ЮMoney для тех, кто развивает продукты, — и собрали записи выступлений. В этот раз говорили о том, как ИИ помогает решать продуктовые задачи: от