简体   繁体   English

Spring 引导 2.2.6 - 安全 | 更新用户信息后如何更新 Principal

[英]Spring Boot 2.2.6 - Security | How to update Principal after updating user's information

On my website when a user is logged in he can access his data (password, email...) and modify them if he wants via a form.在我的网站上,当用户登录时,他可以访问他的数据(密码,email...),如果他愿意,可以通过表单修改它们。 The data are processed and the DB is updated with the new data.处理数据并使用新数据更新 DB。 But, the data currently used and kept by Spring (as Principal) are outdated.但是,Spring(作为校长)当前使用和保存的数据已经过时。 I'm currently forced to disconnect the user so that he connects himself again to retrieve the "good" data but that's not really... ergonomic.我目前被迫断开用户的连接,以便他再次连接自己以检索“好”数据,但这并不是真的......符合人体工程学。

How can I "refresh" the Principal object without direct log out/in?如何在不直接注销/登录的情况下“刷新”主体 object?

Thanks for your help !谢谢你的帮助 !

Controller method managing user update: Controller 方法管理用户更新:

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

Found an answer by myself: https://stackoverflow.com/a/7267941/12642186自己找到了答案: 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;
}

Since Java is all about reference, directly updating the principal object cast as a custom userDetails will "update" it and prevent you from log out/in the user.由于 Java 都是关于参考的,因此直接将主体 object 转换为自定义 userDetails 将“更新”它并阻止您注销/登录用户。

My custom UserDetails class:我的自定义 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;
    }
}

So I guess some generic code should looks like this:所以我猜一些通用代码应该是这样的:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在Spring Boot中从HttpSessionEvent检索主体信息? - How to retrieve principal information from HttpSessionEvent in Spring Boot? Spring Security 中的“主体”是什么? - What's the “principal” in Spring Security? 在Spring Security中成功登录后如何处理用户信息 - How to handle user information after login succeed in Spring Security Spring 引导安全主体用户更改为新登录的用户详细信息 - Spring boot security principal user getting changed to newly logged in user details Spring 启动 Oauth 安全性 - 客户端凭据授予类型中主体中的用户(自定义信息)信息 - Spring boot Oauth security - User(custom info) info in the principal in Client Credentials grant type 如何在spring security中更新用户权限后立即启用权限? - How to immediately enable the authority after update user authority in spring security? Spring Security用户信息 - Spring Security User Information 如何在 Spring Boot Security 中启用或禁用用户 - How to enable or disable user in Spring Boot Security 未找到依赖项 'org.springframework.boot:spring-boot-starter-security:2.2.6.RELEASE' - Dependency 'org.springframework.boot:spring-boot-starter-security:2.2.6.RELEASE' not found java.lang.IllegalStateException:Current user principal is not of type when i try to integrate keycloak with spring boot web + spring security project - java.lang.IllegalStateException:Current user principal is not of type when i try to integrate keycloak with spring boot web + spring security project
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM