Um Spring SecurityConfigurer personalizado
1. Visão geral
O suporte à configuração Java do Spring Security fornece uma poderosa API fluente - para definir mapeamentos e regras de segurança para um aplicativo.
Neste artigo rápido, veremos como podemos dar um passo adiante e realmente definir um configurador personalizado; this is an advanced and flexible way to introduce custom logic into a standard security configuration.
Para nosso exemplo rápido aqui, adicionaremos uma funcionalidade que registra erros para usuários autenticados, dependendo de uma determinada lista de códigos de status de erro.
2. UmSecurityConfigurer personalizado
Para começar a definir nosso configurador, primeirowe need to extend the AbstractHttpConfigurer class:
public class ClientErrorLoggingConfigurer
extends AbstractHttpConfigurer {
private List errorCodes;
// standard constructors
@Override
public void init(HttpSecurity http) throws Exception {
// initialization code
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.addFilterAfter(
new ClientErrorLoggingFilter(errorCodes),
FilterSecurityInterceptor.class);
}
}
Aqui,the main method we need to override is the configure() method - que contém a configuração de segurança à qual este configurador se aplicará.
Em nosso exemplo, registramos um novo filtro após o último filtro Spring Security. Além disso, como pretendemos registrar os códigos de erro de status de resposta, adicionamos uma propriedadeerrorCodes List que podemos usar para controlar os códigos de erro que registraremos.
Também podemos opcionalmente adicionar configuração adicional no métodoinit(), que é executado antes do métodoconfigure().
A seguir, vamos definir a classe de filtro Spring Security que registramos em nossa implementação personalizada:
public class ClientErrorLoggingFilter extends GenericFilterBean {
private static final Logger logger = LogManager.getLogger(
ClientErrorLoggingFilter.class);
private List errorCodes;
// standard constructor
@Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
//...
chain.doFilter(request, response);
}
}
Esta é uma classe de filtro Spring padrão que estendeGenericFilterBeane substitui o métododoFilter(). Ele tem duas propriedades que representam o registrador que usaremos para exibir mensagens e oList deerrorCodes.
Vamos dar uma olhada mais de perto no métododoFilter():
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth == null) {
chain.doFilter(request, response);
return;
}
int status = ((HttpServletResponse) response).getStatus();
if (status < 400 || status >= 500) {
chain.doFilter(request, response);
return;
}
if (errorCodes == null) {
logger.debug("User " + auth.getName() + " encountered error " + status);
} else {
if (errorCodes.stream().anyMatch(s -> s.value() == status)) {
logger.debug("User " + auth.getName() + " encountered error " + status);
}
}
Se o código de status for um código de status de erro do cliente, o que significa entre 400 e 500, verificaremos a listaerrorCodes.
Se estiver vazio, exibiremos qualquer código de status de erro do cliente. Caso contrário, primeiro verificaremos se o código de erro faz parte dosList de códigos de status fornecidos.
3. Usando o Configurador Personalizado
Agora que temos nossa API personalizada,we can add it to the Spring Security configuration by defining the bean, then by using the apply() method ofHttpSecurity:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
//...
.and()
.apply(clientErrorLogging());
}
@Bean
public ClientErrorLoggingConfigurer clientErrorLogging() {
return new ClientErrorLoggingConfigurer() ;
}
}
Também podemos definir o bean com uma lista específica de códigos de erro que queremos registrar:
@Bean
public ClientErrorLoggingConfigurer clientErrorLogging() {
return new ClientErrorLoggingConfigurer(Arrays.asList(HttpStatus.NOT_FOUND)) ;
}
E isso é tudo! Agora, nossa configuração de segurança incluirá o filtro personalizado e exibirá as mensagens de log.
Se quisermos que o configurador personalizado seja adicionado por padrão, podemos usar o arquivoMETA-INF/spring.factories:
org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer = com.example.dsl.ClientErrorLoggingConfigurer
E para desativá-lo manualmente, podemos usar o métododisable():
//...
.apply(clientErrorLogging()).disable();
4. Conclusão
Neste tutorial rápido, focamos em um recurso avançado do suporte de configuração do Spring Security -we’ve seen how to define our own, custom SecurityConfigurer.
Como sempre, o código-fonte completo do exemplo pode ser encontradoover on GitHub.