Spring Security AuthenticationFailureHandler
1. Visão geral
Neste tutorial rápido, vamos ilustrar como personalizar o tratamento de falhas de autenticação de do Spring Security em um aplicativo Spring Boot. O objetivo é autenticar usuários usando uma abordagemform login.
2. Autenticação e autorização
Authentication eAuthorization são frequentemente usados em conjunto porque desempenham um papel essencial e igualmente importante quando se trata de conceder acesso ao sistema.
No entanto, eles têm significados diferentes e aplicam restrições diferentes ao validar uma solicitação:
-
Authentication - precedeAuthorization;, trata-se de validar as credenciais recebidas; é onde verificamos se o nome de usuário e a senha correspondem aos que nosso aplicativo reconhece
-
Authorization–enta-se sobre como verificar se o usuário autenticado com sucesso tem permissões para acessar uma determinada funcionalidade do aplicativo
Podemos personalizar o tratamento de falhas deauthentication eauthorization, no entanto, neste aplicativo, vamos nos concentrar nas falhas de autenticação.
3. Spring Security’sAuthenticationFailureHandler
Spring Security fornece um componente que lida com falhas de autenticação para nós por padrão.
No entanto, não é incomum nos encontrarmos em um cenário onde o comportamento padrão não é suficiente para atender aos requisitos.
Se for esse o caso, podemos criar nosso próprio componente e fornecer o comportamento personalizado que desejamos implementando a interfaceAuthenticationFailureHandler:
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));
}
}
Por padrão,Springredirects o usuário volta para a página de login comrequest parameter contendo informações sobre o erro.
Neste aplicativo, retornaremos uma resposta 401 que contém informações sobre o erro, bem como o carimbo de data / hora de sua ocorrência.
Além do componente padrão,Spring tem outros componentes prontos para usar que podemos aproveitar dependendo do que queremos fazer:
-
DelegatingAuthenticationFailureHandler delegaAuthenticationException subclasses para diferentesAuthenticationFailureHandlers, o que significa que podemos criar diferentes comportamentos para diferentes instâncias deAuthenticationException
-
ExceptionMappingAuthenticationFailureHandler redireciona o usuário para um URL específico, dependendo do nome da classeAuthenticationException’s full
-
ForwardAuthenticationFailureHandler encaminhará o usuário para a URL especificada, independentemente do tipo deAuthenticationException
-
SimpleUrlAuthenticationFailureHandler é o componente que é usado por padrão, ele redirecionará o usuário para umfailureUrl, if especificado; caso contrário, ele simplesmente retornará uma resposta 401
Agora que criamos nossoAuthenticationFailureHandler personalizado, vamos configurar nosso aplicativo e substituir o manipulador padrão deSpring’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();
}
}
Observe a escalafailureHandler(), é onde podemos dizer aSpring para usar nosso componente personalizado em vez de usar o padrão.
4. Conclusão
Neste exemplo, personalizamos o manipulador de falha de autenticação de nosso aplicativo aproveitando a interfaceSpring’s AuthenticationFailureHandler.
A implementação deste exemplo pode ser encontrada emthe Github project.
Ao executar localmente, você pode acessar e testar o aplicativo emlocalhost:8080