import jakarta.persistence.*;
@Entity
@Table(name = "Utilisateurs")
public class Utilisateur {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long idUtilisateur;
@Column(nullable = false, length = 60)
private String nomUtilisateur;
@Column(nullable = false, length = 60)
private String prenom ;
@Column(nullable = false, length = 60 ,unique = true)
private String adresseEmail;
@Column(nullable = false, length = 250)
private String motDePasse;
@Column(nullable = false, length = 60)
private String role;
public Utilisateur() {}
}
Ajoutez dans ressources -> application.properties ,
# database configurations
spring.datasource.url=jdbc:mysql://localhost:3306/spring_DB?createDatabaseIfNotExist=tru e&useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
Pour l'inscription d'un user
https://www.javadevjournal.com/spring-security/registration-with-spring-security/
dans le fichier pom.xml ajoutez
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
Spring Security Login | Java Development Journal (javadevjournal.com)
Package Model
import javax.persistence.*;
import java.util.Objects;
@Entity
@Table(name = "user")
public class UserEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
@Column(unique = true)
private String email;
private String password;
private boolean accountVerified;
public Long getId() {
return id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isAccountVerified() {
return accountVerified;
}
public void setAccountVerified(boolean accountVerified) {
this.accountVerified = accountVerified;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserEntity that = (UserEntity) o;
return Objects.equals(email, that.email);
}
@Override
public int hashCode() {
return Objects.hash(email);
}
}
ConfigSecurity
1. Ajouter dans le package security une classe SecurityConfiguration.java
Définition de Spring Security
Spring Security est un Framework de sécurité léger qui fournit une authentification et un support d’autorisation afin de sécuriser les applications Spring. Il est livré avec des implémentations d’algorithmes de sécurité populaires.
Cette classe propose plusieurs méthodes pour configurer notre configuration de sécurité.
protected void configure (HttpSecurity http): cette méthode incorporera toutes les demandes autorisées et les URL permis à l’accès public dans l’application et celles qui sont sécurisées. Dans notre cas, nous autorisons l’accès à tous uniquement pour la page d’accueil. Toute autre demande des utilisateurs doit être sur l’authentification avant l’accès. Nous avons également la possibilité de définir une page de connexion pour les utilisateurs authentifiés.
protected void configure (AuthenticationManagerBuilder authManagerBuilder):
cette méthode de substitution permet de spécifier à l’AuthentificationManagerBuilder les types UserDetailsService et PasswordEncoder que nous allons utiliser.
L’interface UserDetailsService est utilisée pour récupérer des données relatives à l’utilisateur. Il possède une méthode appelée loadUserByUsername () qui trouve une entité utilisateur en fonction du nom d’utilisateur et peut être remplacée pour personnaliser le processus de recherche de l’utilisateur.
package com.example.demo.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import javax.annotation.Resource;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Resource
private UserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login","/register")
.permitAll()
.and()
.formLogin().defaultSuccessUrl("/account/home")
.loginPage("/login")
.failureUrl("/login?error=true")
.and();
}
@Bean
public DaoAuthenticationProvider authProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authProvider());
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
@Override
protected void configure(HttpSecurity http) throws Exception{
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/signup").permitAll()
.antMatchers("/home").permitAll()
.antMatchers("/logout").permitAll()
.antMatchers("/user/**","/spectacle/**","/representation/**").hasAuthority("Admin").anyRequest()
.authenticated().and().csrf().disable()
.formLogin().loginPage("/login").failureUrl("/login?error=true")
.defaultSuccessUrl("/home")
.usernameParameter("email")
.passwordParameter("password")
.and().logout().logoutUrl("/logout").logoutSuccessUrl("/login")
.and().exceptionHandling().accessDeniedPage("/access_denied");
}
Cette classe hérite de la classe JpaRepository. La fonction findByUserEmail (String email) permet de récupérer un User à partir de son email.
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.example.demo.entity.UserEntity;
@Repository
public interface UserRepository extends JpaRepository<UserEntity, Long> {
UserEntity findByEmail(String email);
}
3 . dans le package Service ajoutez la classe suivante:
package com.example.demo.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.core.userdetails.User;
import com.example.demo.entity.UserEntity;
import com.example.demo.repository.UserRepository;
import org.springframework.stereotype.Service;
@Service
public class CustomUserDetailService implements UserDetailsService {
@Autowired
UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
final UserEntity customer = userRepository.findByEmail(email);
if (customer == null) {
throw new UsernameNotFoundException(email);
}
UserDetails user = User.withUsername(customer.getEmail())
.password(customer.getPassword())
.authorities("USER").build();
return user;
}
}
3 package Controller
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class LoginPageController {
@GetMapping("/login")
public String login(){
return "account/login";
}
}
Initialiser votre base de données
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import com.example.demo.entity.UserEntity;
import com.example.demo.repository.UserRepository;
@Service
public class DbInit implements CommandLineRunner {
@Autowired
UserRepository userRepository ;
@Autowired
private PasswordEncoder passwordEncoder ;
@Override
public void run(String... args) throws Exception {
// TODO Auto-generated method stub
userRepository.deleteAll();
UserEntity user = new UserEntity();
user.setEmail("sguerfi12@yahoo.com");
user.setFirstName("TOTO");
user.setLastName("TOTO");
user.setAccountVerified(true);
user.setPassword(passwordEncoder.encode("1234"));
UserEntity user1 = new UserEntity();
user1.setEmail("sguerfi12@gmail.com");
user1.setFirstName("TITI");
user1.setLastName("TITI");
user1.setAccountVerified(true);
user1.setPassword(passwordEncoder.encode("12345"));
List<UserEntity> liste = new ArrayList<>();
liste.add(user);
userRepository.saveAndFlush(user);
liste.add(user1);
userRepository.saveAndFlush(user1);
}
}
Créer un dossier user dans le package template
Ensuite dans le dossier account ajoutez le fichier login.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="en">
<body class="hold-transition login-page">
<div class="login-box">
<div class="login-logo">
<div class="card">
<div class="card-body login-card-body">
<p class="login-box-msg">Sign in to start your session</p>
<p th:if="${loginError}" class="error">Wrong user or password</p>
<form th:action="@{/login}" method="post">
<div th:if="${param.error}">
<div class="alert alert-danger">
Invalid username or password.
</div>
</div>
<div class="input-group mb-3">
<input type="email" class="form-control" name="username" placeholder="Email">
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-envelope"></span>
</div>
</div>
</div>
<div class="input-group mb-3">
<input type="password" name="password" class="form-control" placeholder="Password">
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-lock"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-4">
<button type="submit" class="btn btn-primary btn-block">Sign In</button>
</div>
<!-- /.col -->
</div>
</form>
</body>
</html>