Spring Security:添加“伪登录”以更改用户信息

Posted

技术标签:

【中文标题】Spring Security:添加“伪登录”以更改用户信息【英文标题】:Spring Security: Adding a "pseudo-login" to change user info 【发布时间】:2021-02-11 01:41:14 【问题描述】:

我注意到几乎每个带有“更改用户信息”表单的 web 应用都需要密码才能接受某些字段。我正在尝试将该功能整合到一个简单的项目中,但我缺少 Spring Security 方面的一些关键步骤。

这是我尝试构建它没有 Spring Security 验证。

前端(JSP):

<form class="form mt-3" id="user-controls-form" method="POST" action="edituserinfo">
    <div class="form-group row align-items-center">
        <div class="col-md-4"><label class="col-form-label" for="username">Username:</label></div>
        <div class="col-md-8"><input type="text" class="form-control" name="username"></div>
    </div>
    <div class="form-group row align-items-center">
        <div class="col-md-4"><label class="col-form-label" for="email">Email:</label></div>
        <div class="col-md-8"><input type="email" class="form-control" name="email"></div>
    </div>
    <div class="form-group row align-items-center">
        <div class="col-md-4"><label class="col-form-label" for="current-password">Current Password:</label></div>
        <div class="col-md-8"><input type="password" class="form-control" name="current-password" required></div>
    </div>
    <div class="form-group row align-items-center">
        <div class="col-md-4"><label class="col-form-label" for="new-password">New Password:</label></div>
        <div class="col-md-8"><input type="password" class="form-control" name="new-password" placeholder="(if changing)"></div>
    </div>
    <div class="form-group row align-items-center">
        <div class="col offset-md-4"><button type="submit" class="btn btn-primary mr-sm-2">Save</button></div>
    </div>
</form>

后端(Spring MVC):

@RequestMapping(value = "/edituserinfo", method=RequestMethod.POST)
public String editUserInfo(HttpServletRequest request, Authentication authentication, Model model) 
    String username = authentication.getName();
    User user = dao.getUserByName(username);
    List<StaticPage> pages = spdao.getAllPages();
    model.addAttribute("pages", pages);

    User editedUser = new User();
    editedUser.setUserID(user.getUserID());
    editedUser.setAuthorities(user.getAuthorities());
    editedUser.setEnabled(user.isEnabled());

    if (request.getParameter("username").isBlank()) 
        editedUser.setUsername(user.getUsername());
     else 
        editedUser.setUsername(request.getParameter("username"));
    

    if (request.getParameter("new-password").isBlank()) 
        editedUser.setPassword(user.getPassword());
     else 
        String clearPw = request.getParameter("new-password");
        String hashPw = encoder.encode(clearPw);
        editedUser.setPassword(hashPw);
    

    if (request.getParameter("email").isBlank()) 
        editedUser.setEmail(user.getEmail());
     else 
        editedUser.setEmail(request.getParameter("email"));
    

    String clearPw = request.getParameter("current-password");
    String hashPw = encoder.encode(clearPw);
    if (hashPw.equals(user.getPassword())) 
        dao.updateUser(editedUser);
    

    return "redirect:usercontrols";

问题是(显然?)新散列编码的“当前密码”值与用户的实际当前密码散列码不匹配,即使明文值相同。我知道 Spring Security 的登录功能可以解决这个问题,但我只将它用于登录。如何在此页面上创建“伪登录”功能,以便用户在不输入当前密码的情况下无法更改其信息?

【问题讨论】:

【参考方案1】:

与其自己比较它们,不如考虑使用PasswordEncoder#matches。来自 JavaDoc:

/**
 * Verify the encoded password obtained from storage matches the submitted raw
 * password after it too is encoded. Returns true if the passwords match, false if
 * they do not. The stored password itself is never decoded.
 * @param rawPassword the raw password to encode and match
 * @param encodedPassword the encoded password from storage to compare with
 * @return true if the raw password, after encoding, matches the encoded password from
 * storage
 */

所以,改为:

String clearPw = request.getParameter("current-password");
if (encoder.matches(clearPw, user.getPassword())) 
    dao.updateUser(editedUser);

【讨论】:

以上是关于Spring Security:添加“伪登录”以更改用户信息的主要内容,如果未能解决你的问题,请参考以下文章

Spring cloud eureka 添加 spring-security

添加“spring-security-taglibs”后jsp中仍然报错:找不到spring security标签的标签库描述符

Spring Security - 多种配置 - 添加 LogoutHandler

如何在 Spring WebFlux Security(Reactive Spring Security)配置中将多个用户角色添加到单个 pathMatcher/Route?

将标头添加到 oauth/token 响应(spring-security)

Spring 3,Spring Security,LDAP,如何向 LDAP 添加角色?