Commit 6029d52bf459b596c1584e13c3c65cf0042898fd
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
Showing
10 changed files
with
126 additions
and
53 deletions
Show diff stats
PFE06/src/main/java/com/PFE/ServerManager/Customer.java
1 | package com.PFE.ServerManager; | 1 | package com.PFE.ServerManager; |
2 | 2 | ||
3 | import javax.persistence.*; | 3 | import javax.persistence.*; |
4 | +import java.util.Set; | ||
4 | 5 | ||
5 | @Entity | 6 | @Entity |
6 | @Table(name = "customer") // NE PAS utiliser "User" car c'est un mot clef réservé pour PostgreSQL | 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,24 +17,31 @@ public class Customer{ | ||
16 | @Column(name = "password") | 17 | @Column(name = "password") |
17 | private String password; | 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 | @JoinTable(name = "customer_role", joinColumns = @JoinColumn(name = "customer_id"), inverseJoinColumns = @JoinColumn(name = "role_id")) | 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 | public void setId(Integer id) { | 30 | public void setId(Integer id) { |
29 | this.customer_id = id; | 31 | this.customer_id = id; |
30 | } | 32 | } |
33 | + public Integer getCustomer_id() { return customer_id; } | ||
31 | 34 | ||
32 | public void setPseudo(String pseudo) { | 35 | public void setPseudo(String pseudo) { |
33 | this.pseudo = pseudo; | 36 | this.pseudo = pseudo; |
34 | } | 37 | } |
38 | + public String getPseudo() { return pseudo; } | ||
35 | 39 | ||
36 | public void setPassword(String password) { | 40 | public void setPassword(String password) { |
37 | this.password = password; | 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 | \ No newline at end of file | 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,6 +4,10 @@ import org.springframework.beans.factory.annotation.Autowired; | ||
4 | import org.springframework.stereotype.Controller; | 4 | import org.springframework.stereotype.Controller; |
5 | import org.springframework.web.bind.annotation.*; | 5 | import org.springframework.web.bind.annotation.*; |
6 | import org.springframework.web.servlet.ModelAndView; | 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 | @Controller | 12 | @Controller |
9 | public class MainController { | 13 | public class MainController { |
@@ -14,9 +18,22 @@ public class MainController { | @@ -14,9 +18,22 @@ public class MainController { | ||
14 | @Autowired | 18 | @Autowired |
15 | RoleRepository roleRepository; | 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 | @GetMapping(path="/registration") | 39 | @GetMapping(path="/registration") |
@@ -24,20 +41,28 @@ public class MainController { | @@ -24,20 +41,28 @@ public class MainController { | ||
24 | return "registration";//fait le lien automatiquement avec le page html du même nom //return "redirect:/...."; | 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 | @PostMapping(path="/registration") | 49 | @PostMapping(path="/registration") |
28 | public ModelAndView addNewUser(@RequestParam String pseudo, @RequestParam String password) { | 50 | public ModelAndView addNewUser(@RequestParam String pseudo, @RequestParam String password) { |
29 | //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 | 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 | ModelAndView modelAndView = new ModelAndView(); // il n'est peut être pas utile d'utiliser ModelAndView | 52 | ModelAndView modelAndView = new ModelAndView(); // il n'est peut être pas utile d'utiliser ModelAndView |
31 | Customer n = new Customer(); | 53 | Customer n = new Customer(); |
32 | n.setPseudo(pseudo); | 54 | n.setPseudo(pseudo); |
33 | - n.setPassword(password); | 55 | + n.setPassword(bCryptPasswordEncoder.encode(password)); |
56 | + n.setActive(1); | ||
34 | Customer temp = customerRepository.findByPseudo(pseudo); | 57 | Customer temp = customerRepository.findByPseudo(pseudo); |
35 | 58 | ||
36 | - /*Role nRole = roleRepository.findByRole("ADMIN"); | ||
37 | - n.setRoles(new HashSet<Role>(Arrays.asList(nRole)));*/ | ||
38 | 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é | 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 | role.setRole("ADMIN"); | 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 | if(temp != null) { | 67 | if(temp != null) { |
43 | modelAndView.addObject("ok", "l'utilisateur existe déjà"); | 68 | modelAndView.addObject("ok", "l'utilisateur existe déjà"); |
@@ -46,45 +71,24 @@ public class MainController { | @@ -46,45 +71,24 @@ public class MainController { | ||
46 | else { | 71 | else { |
47 | modelAndView.addObject("ok", "l'utilisateur a bien été ajouté"); | 72 | modelAndView.addObject("ok", "l'utilisateur a bien été ajouté"); |
48 | customerRepository.save(n); | 73 | customerRepository.save(n); |
49 | - } | 74 | + } |
50 | modelAndView.setViewName("registration"); | 75 | modelAndView.setViewName("registration"); |
51 | return modelAndView; | 76 | return modelAndView; |
52 | } | 77 | } |
53 | 78 | ||
54 | @GetMapping(path="/login") | 79 | @GetMapping(path="/login") |
55 | - public ModelAndView login(){ | 80 | + public ModelAndView login() { |
56 | ModelAndView modelAndView = new ModelAndView(); | 81 | ModelAndView modelAndView = new ModelAndView(); |
57 | modelAndView.setViewName("login"); | 82 | modelAndView.setViewName("login"); |
58 | return modelAndView; | 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 | @GetMapping(path="/all") | 86 | @GetMapping(path="/all") |
83 | public @ResponseBody Iterable<Customer> getAllUsers() { | 87 | public @ResponseBody Iterable<Customer> getAllUsers() { |
84 | return customerRepository.findAll(); | 88 | return customerRepository.findAll(); |
85 | } | 89 | } |
86 | 90 | ||
87 | - @RequestMapping(value="/success") | 91 | + @GetMapping(value="/success") |
88 | public String success(){ | 92 | public String success(){ |
89 | return "success"; | 93 | return "success"; |
90 | } | 94 | } |
PFE06/src/main/java/com/PFE/ServerManager/Role.java
@@ -21,4 +21,8 @@ public class Role { | @@ -21,4 +21,8 @@ public class Role { | ||
21 | public void setRole(String role) { | 21 | public void setRole(String role) { |
22 | this.role = role; | 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 | \ No newline at end of file | 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 +6,8 @@ import org.springframework.context.annotation.Configuration; | ||
6 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; | 6 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; |
7 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; | 7 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
8 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; | 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 | import javax.sql.DataSource; | 12 | import javax.sql.DataSource; |
11 | 13 | ||
@@ -17,27 +19,38 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { | @@ -17,27 +19,38 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { | ||
17 | DataSource dataSource; | 19 | DataSource dataSource; |
18 | 20 | ||
19 | @Autowired | 21 | @Autowired |
22 | + private BCryptPasswordEncoder passwordEncoder; | ||
23 | + | ||
24 | + @Autowired | ||
20 | public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception { | 25 | public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception { |
21 | auth.jdbcAuthentication() | 26 | auth.jdbcAuthentication() |
22 | .dataSource(dataSource) | 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 | @Override | 33 | @Override |
28 | protected void configure(HttpSecurity http) throws Exception { | 34 | protected void configure(HttpSecurity http) throws Exception { |
29 | http | 35 | http |
30 | .authorizeRequests() | 36 | .authorizeRequests() |
31 | - .antMatchers("/").permitAll() | 37 | + .antMatchers("/home").hasAuthority("ADMIN") |
32 | .antMatchers("/registration").permitAll() | 38 | .antMatchers("/registration").permitAll() |
33 | .antMatchers("/login").permitAll() | 39 | .antMatchers("/login").permitAll() |
34 | - //.antMatchers("/registration").hasRole("ADMIN").anyRequest().authenticated() | 40 | + .antMatchers("/denied").permitAll() |
41 | + .anyRequest().authenticated() | ||
35 | .and() | 42 | .and() |
36 | .formLogin() | 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 | .and() | 48 | .and() |
39 | .logout() | 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 | \ No newline at end of file | 57 | \ No newline at end of file |
PFE06/src/main/java/com/PFE/ServerManager/WebMvcConfig.java
0 → 100644
@@ -0,0 +1,16 @@ | @@ -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 | \ No newline at end of file | 17 | \ No newline at end of file |
PFE06/src/main/resources/application.properties
@@ -8,9 +8,9 @@ spring.jpa.hibernate.ddl-auto=create | @@ -8,9 +8,9 @@ spring.jpa.hibernate.ddl-auto=create | ||
8 | #"update" met à jour la base données | 8 | #"update" met à jour la base données |
9 | 9 | ||
10 | #Simon Postgres config : | 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 | spring.datasource.username=postgres | 12 | spring.datasource.username=postgres |
13 | -spring.datasource.password=idalurf123 | 13 | +spring.datasource.password=admin |
14 | 14 | ||
15 | #Antoine Postgres config : | 15 | #Antoine Postgres config : |
16 | #spring.datasource.url=jdbc:postgresql://localhost:3302/sql_only | 16 | #spring.datasource.url=jdbc:postgresql://localhost:3302/sql_only |
PFE06/src/main/resources/data.sql
1 | /* ce fichier doit être placé dans les ressources afin d'être utilisé */ | 1 | /* ce fichier doit être placé dans les ressources afin d'être utilisé */ |
2 | INSERT INTO "role" VALUES (1,'ADMIN'); | 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 | INSERT INTO "customer_role" VALUES (1,1); | 6 | INSERT INTO "customer_role" VALUES (1,1); |
6 | -INSERT INTO "customer_role" VALUES (2,1);*/ | ||
7 | \ No newline at end of file | 7 | \ No newline at end of file |
8 | +INSERT INTO "customer_role" VALUES (2,1); | ||
9 | +*/ | ||
8 | \ No newline at end of file | 10 | \ No newline at end of file |
@@ -0,0 +1,16 @@ | @@ -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 | \ No newline at end of file | 17 | \ No newline at end of file |
PFE06/src/main/resources/templates/home.html
@@ -6,7 +6,17 @@ | @@ -6,7 +6,17 @@ | ||
6 | <title>Page d'accueil</title> | 6 | <title>Page d'accueil</title> |
7 | </head> | 7 | </head> |
8 | <body> | 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 | </body> | 21 | </body> |
12 | </html> | 22 | </html> |
13 | \ No newline at end of file | 23 | \ No newline at end of file |
PFE06/src/main/resources/templates/login.html
@@ -6,7 +6,7 @@ | @@ -6,7 +6,7 @@ | ||
6 | </head> | 6 | </head> |
7 | <body> | 7 | <body> |
8 | <div> | 8 | <div> |
9 | - <h5>Ajouter de nouveaux utilisateurs :</h5> | 9 | + <h5>Se connecter :</h5> |
10 | <form th:action="@{/login}" method="POST"> | 10 | <form th:action="@{/login}" method="POST"> |
11 | <div class="form1"> | 11 | <div class="form1"> |
12 | <label for="username">User Name: </label> | 12 | <label for="username">User Name: </label> |
@@ -16,7 +16,7 @@ | @@ -16,7 +16,7 @@ | ||
16 | <label for="password">Password: </label> | 16 | <label for="password">Password: </label> |
17 | <input type="password" id="password" placeholder="Enter Password" name="password"/> | 17 | <input type="password" id="password" placeholder="Enter Password" name="password"/> |
18 | </div> | 18 | </div> |
19 | - <button type="submit">se connecter</button> | 19 | + <button type="submit">Se connecter</button> |
20 | </form> | 20 | </form> |
21 | <span th:utext="${error}"></span> | 21 | <span th:utext="${error}"></span> |
22 | <!--<div th:if="${param.ok}"> | 22 | <!--<div th:if="${param.ok}"> |