Spring 启动 2.2.6 - 安全 |更新用户信息后如何更新Principal
Spring Boot 2.2.6 - Security | How to update Principal after updating user's information
在我的网站上,当用户登录时,他可以访问他的数据(密码、电子邮件...),并根据需要通过表单修改它们。处理数据并使用新数据更新数据库。但是,Spring(作为委托人)当前使用和保存的数据已经过时。我目前被迫断开用户连接,以便他再次连接自己以检索 "good" 数据,但这并不是真的......符合人体工程学。
如何 "refresh" 没有直接日志的 Principal 对象 out/in?
感谢您的帮助!
管理用户更新的控制器方法:
@RequestMapping(value = "/updateUser", method = RequestMethod.POST)
public ModelAndView updateProcess(Principal principal, HttpServletRequest request) {
ModelAndView mv = new ModelAndView();
updateUserService.updateUser(principal.getName(), request);
if (updateUserService.getErrors().isEmpty()) {
mv.setViewName("redirect:/deconnexion");
mv.addObject("page", "index");
} else {
mv.setViewName("members/userUpdate");
mv.addObject("page", "userProfile");
mv.addObject("form", updateUserService);
}
return mv;
}
自己找到答案:
@RequestMapping(value = "/updateUser", method = RequestMethod.POST)
public ModelAndView updateProcess2(Authentication auth, HttpServletRequest request) {
ModelAndView mv = new ModelAndView();
PrincipalUser pu = (PrincipalUser) auth.getPrincipal();
updateUserService.updateUser2(pu.getUser(), request);
if (updateUserService.getErrors().isEmpty()) {
mv.setViewName("members/userProfile");
mv.addObject("page", "userProfile");
} else {
mv.setViewName("members/userUpdate");
mv.addObject("page", "userProfile");
mv.addObject("form", updateUserService);
}
return mv;
}
由于 Java 完全是关于引用的,直接更新主体对象转换为自定义 userDetails 将 "update" 它并阻止您记录 out/in 用户。
我的自定义 UserDetails class :
public class PrincipalUser implements UserDetails {
private static final long serialVersionUID = 1L;
//my personal User class
private User user;
public PrincipalUser(User user) {
super();
this.user = user;
}
public User getUser() {
return user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Collections.singleton(new SimpleGrantedAuthority("USER"));
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getPseudo();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
所以我想一些通用代码应该是这样的:
@RequestMapping(value = "requestName", method = RequestMethod.POST)
public ModelAndView updateProcess(Authentication auth, HttpServletRequest request) {
ModelAndView mv = new ModelAndView();
//cast the Principal as your custom UserDetails
CustomUserDetails cud = (CustomUserDetails) auth.getPrincipal();
//ask a @Service class to process the new data and eventually update the user
updateUserClass.updateUser(cud.whatYouNeed, request);
//if no error while processing then set ModelAndView to your "succes page"
if (updateUserClass.getErrors().isEmpty()) {
mv.setViewName("successPage");
}
//else set ModelAndView to your "form page"
//and, if you want, add the @Service class to show the
//errors and other information in the form
else {
mv.setViewName("formPage");
mv.addObject("form", updateUserClass);
}
return mv;
}
在我的网站上,当用户登录时,他可以访问他的数据(密码、电子邮件...),并根据需要通过表单修改它们。处理数据并使用新数据更新数据库。但是,Spring(作为委托人)当前使用和保存的数据已经过时。我目前被迫断开用户连接,以便他再次连接自己以检索 "good" 数据,但这并不是真的......符合人体工程学。
如何 "refresh" 没有直接日志的 Principal 对象 out/in?
感谢您的帮助!
管理用户更新的控制器方法:
@RequestMapping(value = "/updateUser", method = RequestMethod.POST)
public ModelAndView updateProcess(Principal principal, HttpServletRequest request) {
ModelAndView mv = new ModelAndView();
updateUserService.updateUser(principal.getName(), request);
if (updateUserService.getErrors().isEmpty()) {
mv.setViewName("redirect:/deconnexion");
mv.addObject("page", "index");
} else {
mv.setViewName("members/userUpdate");
mv.addObject("page", "userProfile");
mv.addObject("form", updateUserService);
}
return mv;
}
自己找到答案:
@RequestMapping(value = "/updateUser", method = RequestMethod.POST)
public ModelAndView updateProcess2(Authentication auth, HttpServletRequest request) {
ModelAndView mv = new ModelAndView();
PrincipalUser pu = (PrincipalUser) auth.getPrincipal();
updateUserService.updateUser2(pu.getUser(), request);
if (updateUserService.getErrors().isEmpty()) {
mv.setViewName("members/userProfile");
mv.addObject("page", "userProfile");
} else {
mv.setViewName("members/userUpdate");
mv.addObject("page", "userProfile");
mv.addObject("form", updateUserService);
}
return mv;
}
由于 Java 完全是关于引用的,直接更新主体对象转换为自定义 userDetails 将 "update" 它并阻止您记录 out/in 用户。
我的自定义 UserDetails class :
public class PrincipalUser implements UserDetails {
private static final long serialVersionUID = 1L;
//my personal User class
private User user;
public PrincipalUser(User user) {
super();
this.user = user;
}
public User getUser() {
return user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Collections.singleton(new SimpleGrantedAuthority("USER"));
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getPseudo();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
所以我想一些通用代码应该是这样的:
@RequestMapping(value = "requestName", method = RequestMethod.POST)
public ModelAndView updateProcess(Authentication auth, HttpServletRequest request) {
ModelAndView mv = new ModelAndView();
//cast the Principal as your custom UserDetails
CustomUserDetails cud = (CustomUserDetails) auth.getPrincipal();
//ask a @Service class to process the new data and eventually update the user
updateUserClass.updateUser(cud.whatYouNeed, request);
//if no error while processing then set ModelAndView to your "succes page"
if (updateUserClass.getErrors().isEmpty()) {
mv.setViewName("successPage");
}
//else set ModelAndView to your "form page"
//and, if you want, add the @Service class to show the
//errors and other information in the form
else {
mv.setViewName("formPage");
mv.addObject("form", updateUserClass);
}
return mv;
}