1. Обзор
В этом кратком руководстве мы собираемся проиллюстрировать, как настроить `обработку ошибок аутентификации Spring Security в приложении Spring Boot. Цель состоит в том, чтобы аутентифицировать пользователей с помощью
формы входа в систему
.`
Для ознакомления с Spring Security
и Form Login
в Spring Boot
обратитесь к этой и этой статье соответственно.
2. Аутентификация и авторизация
Аутентификация
и авторизация
часто используются вместе, поскольку они играют существенную и не менее важную роль, когда речь идет о предоставлении доступа к системе.
Однако они имеют разные значения и применяют разные ограничения при проверке запроса:
Аутентификация
– предшествуетАвторизации;
речь идет о проверке полученных учетных данных; именно здесь мы проверяем, совпадают ли имя пользователя и пароль с теми, которые распознает наше приложение.Авторизация
—
это проверка наличия у успешно прошедшего проверку подлинности пользователя разрешений на доступ к определенным функциям приложения.
Мы можем настроить обработку ошибок аутентификации
и авторизации
, однако в этом приложении мы сосредоточимся на ошибках аутентификации.
3. Spring Security AuthenticationFailureHandler
Spring Security
предоставляет компонент, который по умолчанию обрабатывает ошибки аутентификации.
Однако нередко мы оказываемся в ситуации, когда поведения по умолчанию недостаточно для удовлетворения требований.
Если это так, мы можем создать собственный компонент и обеспечить нужное поведение, реализуя интерфейс AuthenticationFailureHandler :
public class CustomAuthenticationFailureHandler
implements AuthenticationFailureHandler {
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public void onAuthenticationFailure(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException exception)
throws IOException, ServletException {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
Map<String, Object> data = new HashMap<>();
data.put(
"timestamp",
Calendar.getInstance().getTime());
data.put(
"exception",
exception.getMessage());
response.getOutputStream()
.println(objectMapper.writeValueAsString(data));
}
}
По умолчанию Spring
перенаправляет
пользователя обратно на страницу входа с параметром запроса,
содержащим информацию об ошибке.
В этом приложении мы вернем ответ 401, содержащий информацию об ошибке, а также отметку времени ее возникновения.
Помимо компонента по умолчанию, в Spring
есть другие готовые к использованию компоненты, которые мы можем использовать в зависимости от того, что мы хотим сделать:
DelegatingAuthenticationFailureHandler
делегирует подклассыAuthenticationException
разным AuthenticationFailureHandlers
, что означает, что мы можем создать различное поведение для разных экземпляровAuthenticationException .
ExceptionMappingAuthenticationFailureHandler
перенаправляет пользователя на определенный URL-адрес в зависимости от полного имени классаAuthenticationException.
ForwardAuthenticationFailureHandler
перенаправит пользователя на указанный URL-адрес независимо от типаисключения AuthenticationException .
SimpleUrlAuthenticationFailureHandler
— это компонент, который используется по умолчанию, он будет перенаправлять пользователя наfailureUrl,
если он указан; в противном случае он просто вернет ответ 401
Теперь, когда мы создали наш собственный AuthenticationFailureHandler
, давайте настроим наше приложение и переопределим обработчик Spring по
умолчанию:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication()
.withUser("user1").password(passwordEncoder.encode("user1Pass")).roles("USER");
}
@Override
protected void configure(HttpSecurity http)
throws Exception {
http
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin()
.failureHandler(authenticationFailureHandler());
}
@Bean
public AuthenticationFailureHandler authenticationFailureHandler() {
return new CustomAuthenticationFailureHandler();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Обратите внимание на вызов failureHandler()
— здесь мы можем указать Spring
использовать наш пользовательский компонент вместо компонента по умолчанию.
4. Вывод
В этом примере мы настроили обработчик ошибок аутентификации нашего приложения, используя интерфейс Spring AuthenticationFailureHandler .
Реализацию этого примера можно найти в проекте Github .
При локальном запуске вы можете получить доступ и протестировать приложение на локальном хосте: 8080.