Depois de muito apanhar do Spring Security estou realizando o login normalmente com meu formulário personalizado, o security está verificando se o usuário está no banco, e depois verifica se a senha é a mesma…
Até ai tudo bem, só que eu preciso ver se o e-mail deste usuário foi validado, minha entidade “Usuario” possui um atributo Boolean chamado “usuarioVerificado” eu gostaria de negar o login quando o usuário ainda não foi verificado, e emitir essa mensagem no meu formulário de login.
Minha config do Spring Security:
@EnableWebSecurity
public class SSConfig extends WebSecurityConfigurerAdapter {
@Autowired
private SSUserService sSUserService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/css/**", "/js/**", "/img/**").permitAll()
.antMatchers("/usuario/**").hasRole("USER")
.antMatchers("/administrador/**").hasRole("ADMIN")
.anyRequest().permitAll()
.and()
.formLogin()
.loginPage("/login")
.usernameParameter("usuarioEmail")
.passwordParameter("usuarioSenha")
.loginProcessingUrl("/checar")
.defaultSuccessUrl("/usuario/lobby", true)
.failureUrl("/login?error")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login?logout")
.permitAll();
//configuracao para conseguir usar o console do h2
http.csrf().disable();
http.headers().frameOptions().disable();
}
@Override
public void configure(AuthenticationManagerBuilder builder) throws Exception {
builder
.userDetailsService(sSUserService)
.passwordEncoder(new BCryptPasswordEncoder());
}
}
O service que traz o Usuário do banco pro Spring Security:
@Service
public class SSUserService implements UserDetailsService {
@Autowired
private UsuarioService usuarioService;
@Autowired
private PermissaoService permissaoService;
@Override
public UserDetails loadUserByUsername(String usuarioEmail) throws UsernameNotFoundException {
Optional<Usuario> optionalUsuario = usuarioService.findByUsuarioEmail(usuarioEmail);
if (!optionalUsuario.isPresent()) {
throw new UsernameNotFoundException("Usuário não encontrado!");
}
if (!optionalUsuario.get().getUsuarioVerificado()) {
throw new UsernameNotFoundException("Usuário não verificado!");
}
return new SSUser(optionalUsuario.get().getUsuarioEmail(), optionalUsuario.get().getUsuarioSenha(), authorities(optionalUsuario.get()));
}
public Collection<? extends GrantedAuthority> authorities(Usuario usuario) {
Collection<GrantedAuthority> auths = new ArrayList<>();
for (Permissao permissao : permissaoService.findByUsuariosIn(usuario)){
auths.add(new SimpleGrantedAuthority("ROLE_" + permissao.getPermissaoNome()));
}
return auths;
}
No service eu consigo fazer essa verificação e lançar um “UsernameNotFoundException”, mas como faço para exibir essa mensagem na página?
Meu formulario html:
<!DOCTYPE html>
<html lang="pt-br"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Swyno - Login</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- Icones do google -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
<!-- CSS do Materialize -->
<link href="/css/materialize.css" rel="stylesheet" type="text/css" />
</head>
<body>
<nav>
<div class="nav-wrapper indigo">
<div class="row">
<div class="col s6 offset-s3">
<a href="#!" class="brand-logo left"><i class="material-icons left">equalizer</i>Swyno</a>
</div>
</div>
</div>
</nav>
<div class="row">
<div class="col s12 offset-s0 m8 offset-m2 l6 offset-l3 xl4 offset-xl4">
<div class="card z-depth-2">
<div class="card-content">
<form name="f" th:action="@{/checar}" th:object="${usuario}" method="post">
<div class="row">
<h5>Login</h5>
</div>
<div class="row">
<div class="input-field">
<i class="material-icons prefix">account_circle</i>
<input th:field="${usuario.usuarioEmail}" id="usuarioEmail" name="usuarioEmail" type="email" class="validate"/>
<label for="usuarioEmail">E-mail</label>
</div>
</div>
<div class="row">
<div class="input-field">
<i class="material-icons prefix">lock</i>
<input th:field="${usuario.usuarioSenha}" id="usuarioSenha" name="usuarioSenha" type="password" pattern=".{3,20}" class="validate"/>
<label for="usuarioSenha">Senha</label>
</div>
</div>
<div class="row">
<div class="input-field">
<button class="btn waves-effect waves-light" type="submit"><i class="material-icons left">send</i>Entrar</button>
</div>
</div>
</form>
</div>
</div>
<div class="row">
<div th:if="${param.error}" class="container red lighten-5">
<p>Credencial informada não corresponde a nenhum usuário válido, ou o e-mail ainda não foi verificado.</p>
</div>
<div th:if="${param.logout}" class="container red lighten-5">
<p>Você saiu do sistema com sucesso.</p>
</div>
</div>
</div>
</div>
<!-- JavaScript no fim do body para melhorar o carregamento -->
<!-- JS do Materialize -->
<script src="/js/materialize.js"></script>
</body>
</html>