Точки входа аутентификации — Spring Security

Для того чтобы Spring Security инициировал процесс аутентификации пользователя используются специальные компоненты — точки входа, которые реализуют интерфейс AuthenticationEntryPoint. Точка входа может инициировать процесс аутентификации в зависимости от выбранного способа аутентификации. Так, если в приложении используется Basic-аутентификация, пользователю будет отправлен HTTP-ответ со статусом 401 Unauthorized и заголовком WWW-Authenticate: Authorize Basic …​, о чём я уже рассказывал в статье о Basic-аутентификации.

Точка входа описывается интерфейсом AuthenticationEntryPoint:

Сигнатура метода commence указывает на то, что точки входа используются для обработки исключений AuthenticationException. Например, фильтры аутентификации используют их для повторного перенаправления пользователя на начало процесса аутентификации в случае, если предыдущая попытка аутентификации завершилась неудачей.

Благодаря доступу к объекту HTTP-ответа точка входа может полностью управлять ответом, который будет отправлен пользователю: задавать нужный код состояния, заголовки и, естественно, содержимое ответа.

Самая простая точка входа — Http403ForbiddenEntryPoint, которая в случае попытки получения не аутентифицированным пользователем доступа к защищённому ресурсу вернёт пользователю HTTP-ответ со статусом 403 Forbidden и пустым телом.

Вы обязательно столкнётесь с этой точкой входа, если не предоставите пользователям каких-либо способов аутентификации, так как она используется по умолчанию.

Регистрация точек входа

Точки входа регистрируются при помощи DSL exceptionHandling настроек цепочки фильтров безопасности. При помощи метода defaultAuthenticationEntryPointFor можно задать точку входа, специфичную для запросов, удовлетворяющих неким требованиям. Например, мы можем потребовать от клиента Basic-аутентификацию для запросов, путь которых начинается с /api, как это показано в примере кода ниже. Если ни одна специфичная точка входа не может быть использована, то будет использована основная точка входа, которая может быть задана при помощи метода authenticationEntryPoint:

Точки входа необязательно указывать явно, если вы используете DSL для фильтров аутентификации, так как они это делают за вас. В приведённом ниже примере DSL для настройки Basic-аутентификации автоматически зарегистрирует в качестве основной точки входа BasicAuthentictionEntryPoint, несмотря на то, что вы не делаете это явно:

Если основная точка входа вообще не указана, то будет использована Http403ForbiddenEntryPoint, указанная выше.

Для некоторых фильтров аутентификации можно указывать собственные точки входа, отличные от глобальных. Например, я хочу использовать в качестве глобальной точки входа BasicAuthenticationEntryPoint, а для фильтра Basic-аутентификации — Http403ForbiddenEntryPoint, сделать я это могу следующим образом:

В этом случае у не аутентифицированного пользователя будет запрошена Basic-аутентификация, но в случае её ошибки будет отправлен пустой HTTP-ответ со статусом 403 Forbidden.

Использование точек входа

Точки входа используются фильтром ExceptionTranslationFilter, который перехватывает два основных типа исключений Spring Security: AuthenticationException и AccessDeniedException.

Если не аутентифицированный пользователь попытается получить доступ к защищённому ресурсу, то AuthorizationFilter выбросит исключение безопасности, в процессе обработки которого ExceptionTranslationFilter попытается его обработать при помощи наиболее подходящей точки входа. При этом ExceptionTranslationFilter сохранит данные запроса в кэше для автоматического перенаправления пользователя на целевую страницу после успешной аутентификации.

Перенаправление пользователя на страницу входа

Допустим, в приложении используется форма входа, и пользователя необходимо перенаправлять на соответствующую страницу /login, сделать это можно следующим образом:

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

Да, при использовании DSL formLogin для настройки формы входа вам не придётся настраивать точку входа вручную, но под капотом будет происходить что-то похожее.

При попытке открыть защищённую страницу не аутентифицированный пользователь будет перенаправлен на страницу /login в результате использования этой точки входа.

Логгирование исключений аутентификации

Точку входа так же можно использовать для логгирования ошибок аутентификации:

Понравилась статья? Тогда поддержки проект и подкинь монетку:

Больше полезных статей и роликов: