我正在使用Sping Boot 创建一个网站。我有一个模板(thymeleaf),用户可以在其中更改密码。但是当用户写入新密码时,密码不会更改。它会重定向到我的主页,但没有任何React。没有错误。
更改密码的后端:
第一个月
@GetMapping("/reset") public String infoLogin(Model model){
model.addAttribute("users",new Users()); return "login/reset";
}
@PostMapping("/reset/{username}") public String pass(@PathVariable("username") String username){
userService.findUsername(username); return "redirect:/index";
}
@Service
@Transactional @PreAuthorize("#username == authentication.name") public Users findUsername(String username){
return this.usersRepo.findByUsername(username);
}
@Repository
@Repository public interface UsersRepo extends JpaRepository<Users,Long> {
Users findByUsername(String username);
}
安全配置:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final UserService userService;
@Autowired
public SecurityConfig( UserService userService) {
this.userService = userService;
}
@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/*","/user/*").hasAuthority("ADMIN")
.antMatchers("/user/*").hasAuthority("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");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
User.UserBuilder userBuilder=User.withDefaultPasswordEncoder();
auth.userDetailsService(userService);
}
@Bean
public PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
模板:
<form method="post" th:action="@{/user/reset/{username}(username=${#authentication.principal.getUsername})}" th:object="${users}">
<input type="hidden" th:field="*{id}">
<div class="form-group">
<label>Username</label>
<input type="text" name="username" class="form-control" th:field="*{username}">
</div>
<div class="form-group">
<label>New Password</label>
<input type="password" id="password" th:field="*{password}" class="form-control">
</div>
<div class="form-group text-right">
<input class="btn btn-primary btn-block" type="submit">
</div>
</form>
在数据库中,它大致如下所示:
| 身份证|电子邮件|用户名|密码|...|
| - ------|- ------|- ------|- ------|- ------|
| 三十四|something@gmail.com|迈赫迪22|小行星1234| ...|
@Entity
@Table(name = "tbl_users")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Users implements Serializable, UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private boolean enabled =true;
@NotBlank
@Size(min = 4,max = 10)
private String username;
@NotBlank
@Size(min = 2,max = 20)
private String name;
@Email
@Column(unique = true)
private String email;
@NotBlank
@Size(min = 8,max = 30)
private String password;
@OneToMany(mappedBy = "user")
private List<Posts> posts;
@ElementCollection(targetClass = Roles.class,fetch = FetchType.EAGER)
@CollectionTable(name = "authorities",joinColumns =
@JoinColumn(name = "username",referencedColumnName = "username") )
@Enumerated(EnumType.STRING)
private List<Roles> roles;
public Users() {
}
public Users(String username, String name, String email, String password) {
this.username = username;
this.name = name;
this.email = email;
this.password = password;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public void setUsername(String username) {
this.username = username;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public List<Posts> getPosts() {
return posts;
}
public void setPosts(List<Posts> posts) {
this.posts = posts;
}
public void setEnabled(boolean enable) {
this.enabled = enable;
}
public List<Roles> getRoles() {
return roles;
}
public void setRoles(List<Roles> roles) {
this.roles = roles;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return roles;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return enabled;
}
}
1条答案
按热度按时间yqhsw0fo1#
但当用户写入新密码时,密码不会更改。
您只是没有在任何地方更改密码。当您发送表单并调用
/reset/{username}
时,您甚至没有查看密码。并为您服务:
除此之外,你应该对你的密码进行哈希运算。想象一下,某个未经授权的人访问了你的数据库。他们可以访问你所有用户的密码。
对于散列密码,请将
PasswordEncoder
更改为不使用NoOpPasswordEncoder
还要注意,您不应该向用户显示他们自己的密码(或哈希)。
为此,请更改
到
我还建议您不要依赖
@PreAuthorize
来检查用户是否真的更改了自己的密码,相反,我会执行以下操作:这总是改变当前用户的密码.它也不要求用户名从前端发送允许你简化你的表单:
如果没有
th:object
,整个表单可能如下所示: