Spring Security Custom AuthenticationFailureHandler

Spring Security Custom AuthenticationFailureHandler

1. обзор

В этом кратком руководстве мы покажем, как настроить обработку сбоев аутентификации pring Security в приложении Spring Boot. Цель - аутентифицировать пользователей с использованием подходаform login.

Для ознакомления сSpring Security иForm Login inSpring Boot, пожалуйста, обратитесь к статьямthis иthis соответственно.

2. Аутентификация и Авторизация

Authentication иAuthorization часто используются вместе, поскольку они играют важную и не менее важную роль, когда дело доходит до предоставления доступа к системе.

Однако они имеют разные значения и применяют разные ограничения при проверке запроса:

  • Authentication - передAuthorization; означает проверку полученных учетных данных; именно здесь мы проверяем, совпадают ли имя пользователя и пароль с теми, которые распознает наше приложение.

  • Authorization- это проверка, есть ли у успешно прошедшего аутентификацию пользователя разрешения на доступ к определенным функциям приложения.

Мы можем настроить обработку ошибок какauthentication, так иauthorization, однако в этом приложении мы сосредоточимся на ошибках аутентификации.

3. AuthenticationFailureHandler Spring Security

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 data = new HashMap<>();
        data.put(
          "timestamp",
          Calendar.getInstance().getTime());
        data.put(
          "exception",
          exception.getMessage());

        response.getOutputStream()
          .println(objectMapper.writeValueAsString(data));
    }
}

По умолчаниюSpringredirects пользователь возвращается на страницу входа сrequest parameter, содержащим информацию об ошибке.

В этом приложении мы вернем ответ 401, содержащий информацию об ошибке, а также отметку времени ее возникновения.

Помимо компонента по умолчанию,Spring имеет другие готовые к использованию компоненты, которые мы можем использовать в зависимости от того, что мы хотим сделать:

  • DelegatingAuthenticationFailureHandler делегирует подклассыAuthenticationException разнымAuthenticationFailureHandlers, что означает, что мы можем создавать разные поведения для разных экземпляровAuthenticationException

  • ExceptionMappingAuthenticationFailureHandler перенаправляет пользователя на определенный URL-адрес в зависимости от имени классаAuthenticationException’s full

  • ForwardAuthenticationFailureHandler перенаправит пользователя на указанный URL-адрес независимо от типаAuthenticationException

  • SimpleUrlAuthenticationFailureHandler - это компонент, который используется по умолчанию, он перенаправляет пользователя на указанныйfailureUrl, if; в противном случае он просто вернет ответ 401

Теперь, когда мы создали собственныйAuthenticationFailureHandler, давайте настроим наше приложение и переопределим обработчик по умолчаниюSpring’s:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration
  extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth)
      throws Exception {
        auth
          .inMemoryAuthentication()
          .withUser("example")
          .password("example")
          .roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http)
      throws Exception {
        http
          .authorizeRequests()
          .anyRequest()
          .authenticated()
          .and()
          .formLogin()
          .failureHandler(customAuthenticationFailureHandler());
    }

    @Bean
    public AuthenticationFailureHandler customAuthenticationFailureHandler() {
        return new CustomAuthenticationFailureHandler();
    }
}

Обратите внимание на scallfailureHandler(), здесь мы можем указатьSpring использовать наш собственный компонент вместо стандартного.

4. Заключение

В этом примере мы настроили обработчик ошибок аутентификации нашего приложения, используя интерфейсSpring’s AuthenticationFailureHandler.

Реализацию этого примера можно найти вthe Github project.

При локальном запуске вы можете получить доступ к приложению и протестировать его наlocalhost:8080

Related