You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot网站密码修改功能失效排查求助

密码修改功能失效的原因排查与解决方案

核心问题点

  • Controller未处理密码更新逻辑:Post请求方法仅查询用户,未接收前端提交的新密码,也未执行数据库更新操作
  • 请求路径不匹配:Thymeleaf表单的action是/user/reset/{username},但Controller的Post映射是/reset/{username},导致请求无法正确映射
  • 缺少密码更新的业务逻辑:Service层仅提供用户查询方法,没有更新密码的实现
  • 表单存在安全隐患:用户名字段可编辑,容易被篡改,且未利用认证信息自动填充

修复后的完整代码

1. Controller层修改

@Controller
@RequestMapping("/user") // 统一前缀,匹配表单路径
public class UserController {

    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/reset")
    public String showResetForm(Model model){
        model.addAttribute("users", new Users());
        return "login/reset";
    }

    // 接收前端提交的表单数据,提取新密码执行更新
    @PostMapping("/reset/{username}")
    public String updatePassword(@PathVariable("username") String username,
                                 @ModelAttribute("users") Users userForm){
        userService.updateUserPassword(username, userForm.getPassword());
        return "redirect:/index";
    }
}

2. Service层新增更新方法

@Service
public class UserService {

    private final UsersRepo usersRepo;

    @Autowired
    public UserService(UsersRepo usersRepo) {
        this.usersRepo = usersRepo;
    }

    @Transactional
    @PreAuthorize("#username == authentication.name")
    public void updateUserPassword(String username, String newPassword){
        Users user = usersRepo.findByUsername(username);
        if(user != null){
            user.setPassword(newPassword);
            usersRepo.save(user); // JPA自动执行数据库更新
        }
    }

    @Transactional
    @PreAuthorize("#username == authentication.name")
    public Users findUsername(String username){
        return this.usersRepo.findByUsername(username);
    }
}

3. Thymeleaf表单修正

<form method="post" th:action="@{/user/reset/{username}(username=${#authentication.principal.username})}" th:object="${users}">
    <input type="hidden" th:field="*{id}">
    <div class="form-group">
        <label>Username</label>
        <!-- 设为只读,利用认证信息填充,避免篡改 -->
        <input type="text" class="form-control" th:value="${#authentication.principal.username}" readonly>
    </div>
    <div class="form-group">
        <label>New Password</label>
        <input type="password" id="password" th:field="*{password}" class="form-control" required>
    </div>
    <div class="form-group text-right">
        <input class="btn btn-primary btn-block" type="submit" value="Update Password">
    </div>
</form>

注:将${#authentication.principal.getUsername}改为${#authentication.principal.username},Thymeleaf可直接通过属性名访问getter方法

4. 安全配置调整

确保/user/reset/**路径允许USER权限访问,修改SecurityConfig的权限匹配规则:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/guest/**","/index/**","/images/**","/css/**","/fonts/**","/js/**","/scripts/**","/server/**","/src/**")
            .permitAll()
            .antMatchers("/admin/**").hasAuthority("ADMIN")
            .antMatchers("/user/**").hasAuthority("USER") // 匹配所有/user开头的路径
            .anyRequest().authenticated()
            .and().formLogin().loginPage("/guest/login").defaultSuccessUrl("/index",true).permitAll()
            .and().rememberMe().rememberMeCookieName("remember").rememberMeParameter("remember")
            .and().logout().deleteCookies("remember").permitAll()
            .and()
            .exceptionHandling().accessDeniedPage("/guest/403");
}

验证步骤

  1. 启动应用,登录用户后访问/user/reset页面
  2. 输入新密码并提交
  3. 查看数据库tbl_users表对应用户的password字段是否更新
  4. 重新登录,使用新密码验证是否生效

内容的提问来源于stack exchange,提问作者mahboy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 04:50:22