0
I am building an application with Spring Security and after performing all settings to have the custom login done with the UserDetailsService
, I realized that when logging in, although the data is recognized and the user is authenticated, the instructions on Thymeleaf as, for example, sec:authorize="hasRole('ADMINISTRADOR')"
are not recognised. On the other hand sec:authorize="isAnonymous()"
is recognized and processed normally. Someone can tell me if there is something wrong with this code that prevents my view from processing the rules?
Gpuserdetailsservice:
import static br.com.dev.util.JdbcUtils.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
@Component
public class GpUserDetailsService implements UserDetailsService {
private static final Logger logger = Logger.getLogger(GpUserDetailsService.class.getSimpleName());
@Autowired
private DataSource dataSource;
@Override
public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {
Connection connection = null;
try {
connection = dataSource.getConnection();
GpUserDetails userDetails = buscarUsuario(connection, login);
Collection<GrantedAuthority> permissoesPorUsuario = buscarPermissoes(connection,
login, PERMISSOES_POR_USUARIO);
// Collection<GrantedAuthority> permissoesPorGrupo = buscarPermissoes(connection,
// login, PERMISSOES_POR_GRUPO);
userDetails.getAuthorities().addAll(permissoesPorUsuario);
// userDetails.getAuthorities().addAll(permissoesPorGrupo);
return userDetails;
} catch (Exception e) {
logger.log(Level.SEVERE, "Problemas com a tentativa de conexão!", e);
throw new UsernameNotFoundException("Problemas com a tentativa de conexão!", e);
} finally {
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
logger.log(Level.SEVERE, "Problemas ao tentar fechar a conexão!", e);
throw new UsernameNotFoundException("Problemas ao tentar fechar a conexão!", e);
}
}
}
public GpUserDetails buscarUsuario(Connection connection, String login) throws SQLException {
PreparedStatement ps = connection.prepareStatement(USUARIO_POR_LOGIN);
ps.setString(1, login);
ResultSet rs = ps.executeQuery();
if (!rs.next()) {
throw new UsernameNotFoundException("Usuário " + login + " não encontrado!");
}
String nomeUsuario = rs.getString("nome_usuario");
String emailUsuario = rs.getString("email_usuario");
String dataNascimentoUsuario = rs.getString("data_nascimento_usuario");
String telefoneUsuario = rs.getString("telefone_usuario");
String sexoUsuario = rs.getString("sexo_usuario");
String senhaUsuario = rs.getString("senha_usuario");
boolean statusUsuario = rs.getBoolean("status_usuario");
rs.close();
ps.close();
return new GpUserDetails(nomeUsuario, emailUsuario, dataNascimentoUsuario, telefoneUsuario, sexoUsuario, senhaUsuario, statusUsuario);
}
public Collection<GrantedAuthority> buscarPermissoes(Connection connection, String login, String sql) throws SQLException {
List<GrantedAuthority> permissoes = new ArrayList<>();
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1, login);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
permissoes.add(new SimpleGrantedAuthority(rs.getString("nome_permissao")));
}
rs.close();
ps.close();
return permissoes;
}
}
Gpuserdetails:
package br.com.dev.security;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.ArrayList;
import java.util.Collection;
public class GpUserDetails implements UserDetails {
private static final long serialVersionUID = 1L;
private String nomeUsuario;
private String emailUsuario;
private String dataNascimentoUsuario;
private String telefoneUsuario;
private String sexoUsuario;
private String senhaUsuario;
private boolean statusUsuario;
private Collection<GrantedAuthority> permissoes = new ArrayList<>();
public GpUserDetails(String nomeUsuario, String emailUsuario, String dataNascimentoUsuario, String telefoneUsuario, String sexoUsuario, String senhaUsuario, boolean statusUsuario) {
this.nomeUsuario = nomeUsuario;
this.emailUsuario = emailUsuario;
this.dataNascimentoUsuario = dataNascimentoUsuario;
this.telefoneUsuario = telefoneUsuario;
this.sexoUsuario = sexoUsuario;
this.senhaUsuario = senhaUsuario;
this.statusUsuario = statusUsuario;
}
@Override
public Collection<GrantedAuthority> getAuthorities() {
return permissoes;
}
public String getNomeUsuario(){
return nomeUsuario;
}
public String getDataNascimentoUsuario() {
return dataNascimentoUsuario;
}
public String getTelefoneUsuario() {
return telefoneUsuario;
}
public String getSexoUsuario() {
return sexoUsuario;
}
@Override
public String getPassword() {
return senhaUsuario;
}
@Override
public String getUsername() {
return emailUsuario;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return statusUsuario;
}
}
User:
import org.hibernate.validator.constraints.NotBlank;
import org.springframework.security.core.GrantedAuthority;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
@Entity
@Table(name = "usuario")
public class Usuario implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long idUsuario;
@NotBlank(message = "O nome não pode ser vazio.")
@NotNull(message = "O nome não pode ser nulo.")
@Column(name = "nomeUsuario")
private String nomeUsuario;
@NotBlank(message = "O e-mail não pode ser vazio.")
@NotNull(message = "O e-mail não pode ser nulo.")
@Column(name = "emailUsuario")
private String emailUsuario;
@NotBlank(message = "A data de nascimento não pode ser vazia.")
@NotNull(message = "A data de nascimento não pode ser nula.")
@Column(name = "dataNascimentoUsuario")
private String dataNascimentoUsuario;
@NotBlank(message = "Pelo menos um telefone deve ser inserido.")
@NotNull(message = "Pelo menos um telefone deve ser inserido.")
@Column(name = "telefoneUsuario")
private String telefoneUsuario;
@NotBlank(message = "O sexo não pode ser vazio.")
@Size(min = 1, max = 1, message = "O sexo deve ser preenchido com M, F ou N.")
@NotNull(message = "O sexo não pode ser vazio.")
@Column(name = "sexoUsuario")
private String sexoUsuario;
@NotBlank(message = "A senha não pode ser vazia.")
@Size(min = 8, message = "A senha deve ter no mínimo 8 digitos.")
@NotNull(message = "A senha não pode ser vazia.")
@Column(name = "senhaUsuario")
private String senhaUsuario;
@Column
@NotNull
private boolean statusUsuario;
@ManyToOne
@JoinColumn(name = "tipoUsuario_fk")
private TipoUsuario tipoUsuario;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
name = "usuario_permissao",
joinColumns = @JoinColumn(name = "usuario_fk"),
inverseJoinColumns = @JoinColumn(name = "permissao_fk")
)
private List<Permissao> permissoes;
public Usuario(String nomeUsuario, String emailUsuario, String dataNascimentoUsuario, String telefone, String sexoUsuario, String senhaUsuario, TipoUsuario tipoUsuario) {
this.nomeUsuario = nomeUsuario;
this.emailUsuario = emailUsuario;
this.dataNascimentoUsuario = dataNascimentoUsuario;
this.telefoneUsuario = telefone;
this.sexoUsuario = sexoUsuario;
this.senhaUsuario = senhaUsuario;
this.tipoUsuario = tipoUsuario;
this.statusUsuario = true;
}
public Usuario() {
}
public long getIdUsuario() {
return idUsuario;
}
public void setIdUsuario(long idUsuario) {
this.idUsuario = idUsuario;
}
public String getNomeUsuario() {
return nomeUsuario;
}
public void setNomeUsuario(String nomeUsuario) {
this.nomeUsuario = nomeUsuario;
}
public String getEmailUsuario() {
return emailUsuario;
}
public void setEmailUsuario(String emailUsuario) {
this.emailUsuario = emailUsuario;
}
public String getDataNascimentoUsuario() {
return dataNascimentoUsuario;
}
public void setDataNascimentoUsuario(String dataNascimentoUsuario) {
this.dataNascimentoUsuario = dataNascimentoUsuario;
}
public String getTelefoneUsuario() {
return telefoneUsuario;
}
public void setTelefoneUsuario(String telefone) {
this.telefoneUsuario = telefone;
}
public String getSexoUsuario() {
return sexoUsuario;
}
public void setSexoUsuario(String sexoUsuario) {
this.sexoUsuario = sexoUsuario;
}
public String getSenhaUsuario() {
return senhaUsuario;
}
public void setSenhaUsuario(String senhaUsuario) {
this.senhaUsuario = senhaUsuario;
}
public TipoUsuario getTipoUsuario() {
return tipoUsuario;
}
public void setTipoUsuario(TipoUsuario tipoUsuario) {
this.tipoUsuario = tipoUsuario;
}
public boolean isStatusUsuario() {
return statusUsuario;
}
public void setStatusUsuario(boolean statusUsuario) {
this.statusUsuario = statusUsuario;
}
public List<Permissao> getPermissoes() {
return permissoes;
}
public void setPermissoes(List<Permissao> permissoes) {
this.permissoes = permissoes;
}
}
Jdbcsecurityconfig:
import static br.com.dev.util.JdbcUtils.*;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@Profile("JDBC")
public class JdbcSecurityConfig {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder builder) throws Exception {
builder
.jdbcAuthentication()
.usersByUsernameQuery(USUARIO_POR_LOGIN)
.authoritiesByUsernameQuery(PERMISSOES_POR_USUARIO);
// .groupAuthoritiesByUsername(PERMISSOES_POR_GRUPO);
}
}
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>br.com.dev</groupId>
<artifactId>ajudaf</artifactId>
<version>1.0-SNAPSHOT</version>
<!--Aqui foi declarada a versão do spring e, portanto, as dependencias não precisam-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
</parent>
<!--Fim-->
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--Dependências padrão para o Spring. (O starter garante um pacote com tudo que precisamos, sem aquele monte de importações)-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>
<!--Fim-->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!--Plugin para comunicação do spring com o maven-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!--Fim-->
</plugins>
</build>
</project>
I can use when configuring users by memory, but when I do with direct authentication in the database it does not process. What puzzles me is that if I make one:
<span sec:authentication="principal.authorities"></span>
and<span sec:authentication="name"></span>
, I get the name and rule, but it is not recognized by Authorize– Bianca Weihs
In the database the role is written this way, ROLE_ADMINISTRATOR ?
– Renan