Commit 6029d52bf459b596c1584e13c3c65cf0042898fd

Authored by Antoine Duquenoy
1 parent eba991ae

Spring Security opérationnel

Pour le moment tout le monde peut se créer un compte et se connecter au site avec. La page d'accueil affiche le pseudo de l'utilisateur.
Par la suite il faudra :
* fixer un admin en BDD
* autoriser la création de compte aux admins
* créer un rôle user classique
PFE06/src/main/java/com/PFE/ServerManager/Customer.java
1 1 package com.PFE.ServerManager;
2 2  
3 3 import javax.persistence.*;
  4 +import java.util.Set;
4 5  
5 6 @Entity
6 7 @Table(name = "customer") // NE PAS utiliser "User" car c'est un mot clef réservé pour PostgreSQL
... ... @@ -16,24 +17,31 @@ public class Customer{
16 17 @Column(name = "password")
17 18 private String password;
18 19  
19   - @ManyToOne(cascade = CascadeType.ALL)
  20 + @Column(name = "active")
  21 + private int active;
  22 +
  23 + @ManyToMany(cascade = CascadeType.ALL)
20 24 @JoinTable(name = "customer_role", joinColumns = @JoinColumn(name = "customer_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
21   - //private Set<Role> roles;
22   - private Role role;
  25 + private Set<Role> roles;
23 26  
24   - public void setRole(Role role) {
25   - this.role = role;
26   - }
  27 + public void setRoles(Set<Role> roles) { this.roles = roles; }
  28 + public Set<Role> getRoles() { return roles; }
27 29  
28 30 public void setId(Integer id) {
29 31 this.customer_id = id;
30 32 }
  33 + public Integer getCustomer_id() { return customer_id; }
31 34  
32 35 public void setPseudo(String pseudo) {
33 36 this.pseudo = pseudo;
34 37 }
  38 + public String getPseudo() { return pseudo; }
35 39  
36 40 public void setPassword(String password) {
37 41 this.password = password;
38 42 }
  43 + public String getPassword() { return password; }
  44 +
  45 + public void setActive(int active) { this.active = active; }
  46 + public int getActive() { return active; }
39 47 }
40 48 \ No newline at end of file
... ...
PFE06/src/main/java/com/PFE/ServerManager/MainController.java
... ... @@ -4,6 +4,10 @@ import org.springframework.beans.factory.annotation.Autowired;
4 4 import org.springframework.stereotype.Controller;
5 5 import org.springframework.web.bind.annotation.*;
6 6 import org.springframework.web.servlet.ModelAndView;
  7 +import java.util.HashSet;
  8 +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  9 +import org.springframework.security.core.context.SecurityContextHolder;
  10 +import org.springframework.security.core.Authentication;
7 11  
8 12 @Controller
9 13 public class MainController {
... ... @@ -14,9 +18,22 @@ public class MainController {
14 18 @Autowired
15 19 RoleRepository roleRepository;
16 20  
17   - @RequestMapping(value="/")
18   - public String home(){
19   - return "home";
  21 + @Autowired
  22 + BCryptPasswordEncoder bCryptPasswordEncoder;
  23 +
  24 + @GetMapping(value="/")
  25 + public String homeRedirection(){
  26 + return "redirect:home";
  27 + }
  28 +
  29 + @GetMapping(value="/home")
  30 + public ModelAndView home() {
  31 + ModelAndView modelAndView = new ModelAndView();
  32 + Authentication auth = SecurityContextHolder.getContext().getAuthentication();
  33 + Customer customer = customerRepository.findByPseudo(auth.getName());
  34 + modelAndView.addObject("customerName", customer.getPseudo());
  35 + modelAndView.setViewName("home");
  36 + return modelAndView;
20 37 }
21 38  
22 39 @GetMapping(path="/registration")
... ... @@ -24,20 +41,28 @@ public class MainController {
24 41 return "registration";//fait le lien automatiquement avec le page html du même nom //return "redirect:/....";
25 42 }
26 43  
  44 + @GetMapping(path="/denied")
  45 + public String denied() {
  46 + return "denied";
  47 + }
  48 +
27 49 @PostMapping(path="/registration")
28 50 public ModelAndView addNewUser(@RequestParam String pseudo, @RequestParam String password) {
29 51 //Model map, ModelAndView ou l'utilisation direct comme dans la méthode précédente sont 3 méthodes qui permettent d'envoyer des informations et donc de changer l'apparence d'une page
30 52 ModelAndView modelAndView = new ModelAndView(); // il n'est peut être pas utile d'utiliser ModelAndView
31 53 Customer n = new Customer();
32 54 n.setPseudo(pseudo);
33   - n.setPassword(password);
  55 + n.setPassword(bCryptPasswordEncoder.encode(password));
  56 + n.setActive(1);
34 57 Customer temp = customerRepository.findByPseudo(pseudo);
35 58  
36   - /*Role nRole = roleRepository.findByRole("ADMIN");
37   - n.setRoles(new HashSet<Role>(Arrays.asList(nRole)));*/
38 59 Role role = new Role(); // l'utilisation d'un role au lieu d'un tableau semble valide, ormis la première ligne de la table qui n'est pas utilisé
39 60 role.setRole("ADMIN");
40   - n.setRole(role);
  61 +
  62 + HashSet<Role> hset = new HashSet<Role>();
  63 + hset.add(role);
  64 +
  65 + n.setRoles(hset);
41 66  
42 67 if(temp != null) {
43 68 modelAndView.addObject("ok", "l'utilisateur existe déjà");
... ... @@ -46,45 +71,24 @@ public class MainController {
46 71 else {
47 72 modelAndView.addObject("ok", "l'utilisateur a bien été ajouté");
48 73 customerRepository.save(n);
49   - }
  74 + }
50 75 modelAndView.setViewName("registration");
51 76 return modelAndView;
52 77 }
53 78  
54 79 @GetMapping(path="/login")
55   - public ModelAndView login(){
  80 + public ModelAndView login() {
56 81 ModelAndView modelAndView = new ModelAndView();
57 82 modelAndView.setViewName("login");
58 83 return modelAndView;
59 84 }
60   - //////// Ne fonctionne pas /////////
61   - /*public String login() {
62   - return "login"; //return "redirect:/...."; //to send a request to redirect the current page
63   - }*/
64   - /*
65   - @PostMapping(path="/login")
66   - public ModelAndView connexion(@RequestParam String pseudo, @RequestParam String password) {
67   - // @RequestParam means it is a parameter from the GET or POST request
68   - //the model Map is used by thymeleaf as a storage for values display on the html page, this is the same way for ModelAndView
69   - ModelAndView modelAndView = new ModelAndView();
70   - Customer temp = customerRepository.findByPseudo(pseudo);
71   - if(temp != null) {
72   - modelAndView.addObject("error", "vous etes autorisé à être sur cette page");
73   - }
74   - else{
75   - modelAndView.addObject("error", "vous n'etes pas autorisé à être sur cette page");
76   - }
77   - modelAndView.setViewName("login");
78   - return modelAndView;
79   - }*/
80   - //////////////////////////
81 85  
82 86 @GetMapping(path="/all")
83 87 public @ResponseBody Iterable<Customer> getAllUsers() {
84 88 return customerRepository.findAll();
85 89 }
86 90  
87   - @RequestMapping(value="/success")
  91 + @GetMapping(value="/success")
88 92 public String success(){
89 93 return "success";
90 94 }
... ...
PFE06/src/main/java/com/PFE/ServerManager/Role.java
... ... @@ -21,4 +21,8 @@ public class Role {
21 21 public void setRole(String role) {
22 22 this.role = role;
23 23 }
  24 + public String getRole() { return role; }
  25 +
  26 + public void setRole_id(Integer role_id) { this.role_id = role_id; }
  27 + public Integer getRole_id() { return role_id; }
24 28 }
25 29 \ No newline at end of file
... ...
PFE06/src/main/java/com/PFE/ServerManager/SecurityConfig.java
... ... @@ -6,6 +6,8 @@ import org.springframework.context.annotation.Configuration;
6 6 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
7 7 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
8 8 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  9 +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  10 +import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
9 11  
10 12 import javax.sql.DataSource;
11 13  
... ... @@ -17,27 +19,38 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
17 19 DataSource dataSource;
18 20  
19 21 @Autowired
  22 + private BCryptPasswordEncoder passwordEncoder;
  23 +
  24 + @Autowired
20 25 public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
21 26 auth.jdbcAuthentication()
22 27 .dataSource(dataSource)
23   - .usersByUsernameQuery("select pseudo, password from customer where pseudo=?")
24   - .authoritiesByUsernameQuery("select u.pseudo, r.role from customer u inner join customer_role ur on(u.customer_id=ur.customer_id) inner join role r on(ur.role_id=r.role_id) where u.pseudo=?");
  28 + .passwordEncoder(passwordEncoder)
  29 + .usersByUsernameQuery("select pseudo, password , active from customer where pseudo=?")
  30 + .authoritiesByUsernameQuery("select c.pseudo, r.role from customer c inner join customer_role cr on(c.customer_id=cr.customer_id) inner join role r on(cr.role_id=r.role_id) where c.pseudo=?");
25 31 }
26 32  
27 33 @Override
28 34 protected void configure(HttpSecurity http) throws Exception {
29 35 http
30 36 .authorizeRequests()
31   - .antMatchers("/").permitAll()
  37 + .antMatchers("/home").hasAuthority("ADMIN")
32 38 .antMatchers("/registration").permitAll()
33 39 .antMatchers("/login").permitAll()
34   - //.antMatchers("/registration").hasRole("ADMIN").anyRequest().authenticated()
  40 + .antMatchers("/denied").permitAll()
  41 + .anyRequest().authenticated()
35 42 .and()
36 43 .formLogin()
37   - .loginPage("/login").failureUrl("/login?error=true").defaultSuccessUrl("/success")
  44 + .loginPage("/login").failureUrl("/login?error=true")
  45 + .defaultSuccessUrl("/success")
  46 + .usernameParameter("pseudo")
  47 + .passwordParameter("password")
38 48 .and()
39 49 .logout()
40   - .permitAll();
41   - //http.exceptionHandling().accessDeniedPage("/403");
  50 + .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
  51 + .logoutSuccessUrl("/")
  52 + .and()
  53 + .exceptionHandling()
  54 + .accessDeniedPage("/denied");
42 55 }
43 56 }
44 57 \ No newline at end of file
... ...
PFE06/src/main/java/com/PFE/ServerManager/WebMvcConfig.java 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +package com.PFE.ServerManager;
  2 +
  3 +import org.springframework.context.annotation.Bean;
  4 +import org.springframework.context.annotation.Configuration;
  5 +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  6 +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  7 +
  8 +@Configuration
  9 +public class WebMvcConfig implements WebMvcConfigurer {
  10 +
  11 + @Bean
  12 + public BCryptPasswordEncoder bCryptpasswordEncoder() {
  13 + return new BCryptPasswordEncoder();
  14 + }
  15 +
  16 +}
0 17 \ No newline at end of file
... ...
PFE06/src/main/resources/application.properties
... ... @@ -8,9 +8,9 @@ spring.jpa.hibernate.ddl-auto=create
8 8 #"update" met à jour la base données
9 9  
10 10 #Simon Postgres config :
11   -spring.datasource.url=jdbc:postgresql://localhost:5432/sql_only
  11 +spring.datasource.url=jdbc:postgresql://localhost:3306/sql_only
12 12 spring.datasource.username=postgres
13   -spring.datasource.password=idalurf123
  13 +spring.datasource.password=admin
14 14  
15 15 #Antoine Postgres config :
16 16 #spring.datasource.url=jdbc:postgresql://localhost:3302/sql_only
... ...
PFE06/src/main/resources/data.sql
1 1 /* ce fichier doit être placé dans les ressources afin d'être utilisé */
2 2 INSERT INTO "role" VALUES (1,'ADMIN');
3   -/*INSERT INTO "customer" VALUES (10,1,'Feutrier','Simon');
4   -INSERT INTO "customer" VALUES (11,1,'Duquenoy','Antoine');
  3 +/*
  4 +INSERT INTO "customer" VALUES (1,1,'Feutrier','Simon');
  5 +INSERT INTO "customer" VALUES (2,1,'Duquenoy','Antoine');
5 6 INSERT INTO "customer_role" VALUES (1,1);
6   -INSERT INTO "customer_role" VALUES (2,1);*/
7 7 \ No newline at end of file
  8 +INSERT INTO "customer_role" VALUES (2,1);
  9 +*/
8 10 \ No newline at end of file
... ...
PFE06/src/main/resources/templates/denied.html 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +<!DOCTYPE html>
  2 +<html xmlns:th="http://www.thymeleaf.org">
  3 +<html lang="en">
  4 +<head>
  5 + <meta charset="UTF-8">
  6 + <title>Access Denied</title>
  7 +</head>
  8 +<body>
  9 + <h1>Access Denied !</h1>
  10 +
  11 + <form th:action="@{/login}" method="GET">
  12 + <button type="Submit">Se connecter</button>
  13 + </form>
  14 +
  15 +</body>
  16 +</html>
0 17 \ No newline at end of file
... ...
PFE06/src/main/resources/templates/home.html
... ... @@ -6,7 +6,17 @@
6 6 <title>Page d'accueil</title>
7 7 </head>
8 8 <body>
9   -<a th:href="@{/login}">connexion</a>
10   -<a th:href="@{/registration}">enregistrer des utilisateurs</a>
  9 +
  10 + <a th:href="@{/login}">Connexion</a>
  11 + <a th:href="@{/registration}">Enregistrer des utilisateurs</a>
  12 +
  13 + <form th:action="@{/logout}" method="GET">
  14 + <button type="Submit">Logout </button>
  15 + </form>
  16 +
  17 +
  18 + <h1 th:utext="${customerName}"> est connecté(e) !</h1>
  19 +
  20 +
11 21 </body>
12 22 </html>
13 23 \ No newline at end of file
... ...
PFE06/src/main/resources/templates/login.html
... ... @@ -6,7 +6,7 @@
6 6 </head>
7 7 <body>
8 8 <div>
9   - <h5>Ajouter de nouveaux utilisateurs :</h5>
  9 + <h5>Se connecter :</h5>
10 10 <form th:action="@{/login}" method="POST">
11 11 <div class="form1">
12 12 <label for="username">User Name: </label>
... ... @@ -16,7 +16,7 @@
16 16 <label for="password">Password: </label>
17 17 <input type="password" id="password" placeholder="Enter Password" name="password"/>
18 18 </div>
19   - <button type="submit">se connecter</button>
  19 + <button type="submit">Se connecter</button>
20 20 </form>
21 21 <span th:utext="${error}"></span>
22 22 <!--<div th:if="${param.ok}">
... ...