[Spring] Impossible de récupérer un "username" pour update
Bonjour, je m'en remets à vous car après plusieurs tentatives et plusieurs heures de recherche je ne comprends pas pourquoi je n'arrive pas à faire un update dans MySQL avec Spring..
Le procédé est le suivant: (pour les .java je vous épargne les imports, pour plus de visibilité)
On part du principe que ce dernier est déjà dans la BDD, il se connecte avec ses identifiants ->
GlobalController.java
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class GlobalController {
@Autowired
private UserService userService;
private User loginUser;
public User getLoginUser() {
if (loginUser == null) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
loginUser = userService.findByUserName(auth.getName());
}
return loginUser;
}
} |
sur cette page de login ->
login.html
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| <!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Login</title>
<meta name="description" content="spring-boot thymeleaf | Login ">
<div th:replace="fragments/header :: header-login-css"></div>
</head>
<body>
<br/>
<hr/>
<div class="container">
<div class="row">
<div class="login-register-form-section">
<h1 class="content-title" align="center">Login</h1><br/>
<div class="tab-content">
<div role="tabpanel" class="tab-pane fade in active" id="login">
<div th:if="${param.error}" class="alert alert-danger alert-dismissable">
<button type="button" class="close" data-dismiss="alert"
aria-hidden="true">×
</button>
Identifiant inconnu.
</div>
<form th:action="@{/login}" method="post" class="form-horizontal">
<div class="form-group ">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-user"></i></div>
<input type="text" name="username" class="form-control"
placeholder="Login" required="required" value=""/>
</div>
</div>
<div class="form-group ">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-key"></i></div>
<input type="password" name="password" class="form-control" placeholder="Mot de passe"
required="required"/>
</div>
</div>
<div class="form-group">
<input type="checkbox" id="rememberMe"/>
<label for="rememberMe">Remember Me </label>
<a href="#" class="pull-right">Mot de passe oublié ?</a>
</div>
<input type="submit" value="Login" class="btn btn-success btn-custom"/>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html> |
grâce a une classe, en cas de succès il est redirigé ->
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| @Component
public class MyAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
private static final Logger logger = LoggerFactory.getLogger(MyAuthenticationSuccessHandler.class);
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
@Override
protected void handle(HttpServletRequest request,
HttpServletResponse response, Authentication authentication) throws IOException {
String targetUrl = determineTargetUrl(authentication);
System.out.println("handle: " + targetUrl);
if (response.isCommitted()) {
logger.warn("Can't redirect");
return;
}
redirectStrategy.sendRedirect(request, response, targetUrl);
}
protected String determineTargetUrl(Authentication authentication) {
logger.info("determineTargetUrl: " + authentication.getName());
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
List<String> roles = new ArrayList<>();
for (GrantedAuthority a : authorities) {
System.out.println("Authority: " + a.getAuthority());
roles.add(a.getAuthority());
}
if (isAdmin(roles)) {
return "/admin" + authentication.getName();
} else if (isUser(roles)) {
return "/home/" + authentication.getName();
} else {
return "/login?error";
}
}
@Override
public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
this.redirectStrategy = redirectStrategy;
}
@Override
protected RedirectStrategy getRedirectStrategy() {
return redirectStrategy;
}
private boolean isUser(List<String> roles) {
return roles.contains("ROLE_USER");
}
private boolean isAdmin(List<String> roles) {
return roles.contains("ROLE_ADMIN");
}
} |
les infos sont obtenus grâce à une classe UserDetails de Spring
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| @Service
public class AuthUserDetailsService implements UserDetailsService {
private static final Logger logger = LoggerFactory.getLogger(AuthUserDetailsService.class);
@Autowired
private UserService userService;
private org.springframework.security.core.userdetails.User springUser;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
User user = getUserDetail(username);
if (user != null) {
springUser = new org.springframework.security.core.userdetails.User(user.getUsername(),
user.getPassword(),
enabled,
accountNonExpired,
credentialsNonExpired,
accountNonLocked,
getAuthorities(user.getRole())
);
return springUser;
} else {
springUser = new org.springframework.security.core.userdetails.User("empty",
"empty",
false,
true,
true,
false,
getAuthorities(1)
);
return springUser;
}
}
public List<GrantedAuthority> getAuthorities(Integer role) {
List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();
if (role == 1) {
authList.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
} else if (role == 2) {
authList.add(new SimpleGrantedAuthority("ROLE_USER"));
}
return authList;
}
private User getUserDetail(String username) {
User user = userService.findByUserName(username);
if (user == null) {
logger.warn("user '" + username + "' on null!");
} else {
logger.info(user.toString());
}
return user;
}
} |
la on est sur le cas d'un ROLE_USER, jusque la tout va bien, donc il a été redirigé sur son "home" qui lui permet directement d'éditer son mot de passe uniquement, on est donc sur le UserController.java
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| @Controller
public class UserController {
private static final Logger logger = LoggerFactory.getLogger(UserController.class);
@Autowired
GlobalController globalController;
@Autowired
UserService userService;
@RequestMapping("/")
public String root(Model model) {
model.addAttribute("reqUser", new User());
logger.info("root");
return "login";
}
@RequestMapping("/login")
public String login(Model model) {
model.addAttribute("reqUser", new User());
logger.info("login");
return "login";
}
@RequestMapping(value = {"/home/editUser"}, method = RequestMethod.POST)
public String edit(@ModelAttribute("editUser") User editUser, Model model) {
logger.info("/home/editUser");
try {
User user = userService.findByUserName(editUser.getUsername());
if (!user.equals(editUser)) {
userService.update(editUser);
model.addAttribute("msg", "success");
} else {
model.addAttribute("msg", "same");
}
} catch (Exception e) {
model.addAttribute("msg", "fail");
logger.error("editUser: " + e.getMessage());
}
model.addAttribute("edit", editUser);
return "home";
}
@RequestMapping(value = "/home/{username}", method = RequestMethod.GET)
public String home(@PathVariable("username") String username, final RedirectAttributes redirectAttributes,
Model model) {
logger.info("/home/{} ", username);
User editUser = userService.findByUserName(username);
if (editUser != null) {
model.addAttribute("editUser", editUser);
return "home";
} else {
redirectAttributes.addFlashAttribute("msg", "notfound");
}
return "redirect:/home";
}
} |
et c'est la ou ça bloque, une fois sur sa page, j'ai bien le "url/home/username" correct (il recupère bien l'username) :
Code:
1 2 3 4 5 6 7 8 9 10 11 12
| [INFO ] 2018-11-23 10:23:37.679 [http-nio-8080-exec-1] UserController - /home/test
Hibernate:
select
user0_.id as id1_0_,
user0_.email as email2_0_,
user0_.password as password3_0_,
user0_.role as role4_0_,
user0_.username as username5_0_
from
user user0_
where
user0_.username=? |
mais quand je veux faire l'édition (donc quand j'appuie sur le bouton) j'ai l'erreur du fail :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13
| [INFO ] 2018-11-23 10:24:08.224 [http-nio-8080-exec-9] UserController - /home/editUser
Hibernate:
select
user0_.id as id1_0_,
user0_.email as email2_0_,
user0_.password as password3_0_,
user0_.role as role4_0_,
user0_.username as username5_0_
from
user user0_
where
user0_.username is null
[ERROR] 2018-11-23 10:24:08.233 [http-nio-8080-exec-9] UserController - editUser: null |
voici le formulaire d'edition:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Edition</title>
<meta name="description" content="spring-boot thymeleaf | Home ">
<div th:replace="fragments/header :: header-login-css"></div>
</head>
<body>
<div th:replace="fragments/header :: header"></div>
<br/><br/><br/>
<hr/>
<div class="container">
<div class="row">
<div class="login-register-form-section">
<h1 class="content-title" align="center">Editer mot de passe</h1><br/>
<div class="tab-content">
<div role="tabpanel" class="tab-pane fade in active" id="home">
<div th:if="${msg eq 'success'}" class="alert alert-success alert-dismissable">
<button type="button" class="close" data-dismiss="alert"
aria-hidden="true">×</button>
<strong>Changement réussi</strong>
</div>
<div th:if="${msg eq 'fail'}" class="alert alert-danger alert-dismissable">
<button type="button" class="close" data-dismiss="alert"
aria-hidden="true">×</button>
<strong>Erreur lors du changement</strong>
</div>
<form th:object="${editUser}" th:action="@{/home/editUser}" method="post"
class="form-horizontal">
<div class="form-group ">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-lock"></i></div>
<input th:field="*{password}" type="password" name="password"
class="form-control" id="password"
placeholder="Mot de passe actuel" required="required"/>
</div>
</div>
<div class="form-group ">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-lock"></i></div>
<input th:field="*{password_1}" type="password" name="password_1"
pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*(),.?:{}|<>]).{8,10}" title="un chiffre, une lettre minuscule, une lettre majuscule, un caractère spécial et un minimum de 8 caractères"
minlength="8" maxlength="10"
class="form-control" id="password_1"
placeholder="Nouveau mot de passe" required="required"/>
</div>
</div>
<div class="form-group ">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-lock"></i></div>
<input th:field="*{password_2}" type="password" name="password_2"
pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*(),.?:{}|<>]).{8,10}" title="un chiffre, une lettre minuscule, une lettre majuscule, un caractère spécial et un minimum de 8 caractères"
minlength="8" maxlength="10"
class="form-control" id="password_2"
placeholder="Confirmation mot de passe" required="required"/>
</div>
</div>
<input type="submit" value="Editer" class="btn btn-success btn-custom"/>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html> |
donc a priori je suis sur que c'est encore un truc à la con mais à passer trop de temps dessus je mouline.
Je pense que le problème se trouve dans un de ses fichiers, je ne sais pas pourquoi il n'arrive pas à recuperer l'username pour l'update alors que pour le login tout va bien...
Merci de votre aide :)
PS: si vous pensez que cela ne vient pas d'un de ses fichiers, je vous donnerais les autres, je ne les mets pas encore car ça fait déjà un paquet de code et je ne suis pas sur que ça vient des autres..
Merciiii