Spring Boot 2.2.6-安全性更新用户信息后如何更新主体

时间:2020-05-13 18:55:28

标签: java spring-boot authentication spring-security updates

在我的网站上,当用户登录时,他可以访问他的数据(密码,电子邮件...),并根据需要通过表格进行修改。将处理数据,并使用新数据更新数据库。但是,Spring(作为Principal)当前使用和保留的数据已过时。我目前被迫断开与用户的连接,以便他再次连接自己以检索“良好”数据,但这并不是真的……符合人体工程学。

如何在不直接注销/登录的情况下“刷新” Principal对象?

感谢您的帮助!

管理用户更新的控制器方法:

@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;
}

1 个答案:

答案 0 :(得分:1)

我自己找到了一个答案: https://stackoverflow.com/a/7267941/12642186

@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的主体对象将“更新”它,并阻止您注销/登录用户。

我的自定义UserDetails类:

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;
}