spring security可以';即使凭据正确,也无法登录

spring security可以';即使凭据正确,也无法登录,spring,spring-boot,spring-security,Spring,Spring Boot,Spring Security,即使在登录表单上提供了正确的凭据,我也无法登录 login.html <div class="col-md-offset-3 col-md-6"> <div th:if="${param.error != null}" style="color: red;">Incorrect Username or Password!</div> <form th:action="@{/login}" method="post">

即使在登录表单上提供了正确的凭据,我也无法登录

login.html

<div class="col-md-offset-3 col-md-6">
        <div th:if="${param.error != null}" style="color: red;">Incorrect Username or Password!</div>
        <form th:action="@{/login}" method="post">
            <div class="imgcontainer">
                <img src="/image/img_avatar2.png" alt="Avatar" class="avatar" >
            </div>

            <div class="form-container">
                <label><b>Username</b></label>
                <input type="text" placeholder="Enter Username" name="username" required>

                <label><b>Password</b></label>
                <input type="password" placeholder="Enter Password" name="password" required>

                <button type="submit">Login</button>
                <input type="checkbox" checked="checked"> Remember me
            </div>

            <div class="form-container" style="background-color:#f1f1f1">
                <button type="button" class="cancelbtn">Cancel</button>
                <span class="psw">Forgot <a href="#">password?</a></span>
            </div>
        </form>
    </div>
UserSecurityService.java

 @EnableWebSecurity
 @Configuration
 @EnableGlobalMethodSecurity(prePostEnabled = true)
 public class SecurityConfig extends WebSecurityConfigurerAdapter {


@Autowired
private UserSecurityService userSecurityService;

@Autowired
private BCryptPasswordEncoder passwordEncoder(){
    return SecurityUtility.passwordEncoder();
}

private static final String[] PUBLIC_MATCHERS={
        "/css/**",
        "/js/**",
        "/image/**",
        "/login",
        "/register",
        "/fonts/**",
        "/newUser",
        "/forgetPassword",
        "/"
};

@Override
protected void configure(HttpSecurity http) throws Exception{

    http
            .authorizeRequests().
            antMatchers(PUBLIC_MATCHERS).
            permitAll().anyRequest().authenticated();

    http
            .csrf().disable().cors().disable()
            .formLogin().failureUrl("/login?error")
            .loginPage("/login").permitAll()
            .defaultSuccessUrl("/")
            .and()
            .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .logoutSuccessUrl("/?logout").deleteCookies("remember-me").permitAll()
            .and()
            .rememberMe();
}

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
    auth.userDetailsService(userSecurityService).passwordEncoder(passwordEncoder());
}

}
@Service
public class UserSecurityService implements UserDetailsService {

@Autowired
private UserRepository userRepository;

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

    Users users = userRepository.findByUsername(username);
    if(users==null){
        throw new UsernameNotFoundException("Username not found");
    }
    return users;
}
}
@Component
public class SecurityUtility {
private static final String SALT = "salt"; // Salt should be protected carefully

@Bean
public static BCryptPasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder(12, new SecureRandom(SALT.getBytes()));
}

@Bean
public static String randomPassword() {
    String SALTCHARS = "ABCEFGHIJKLMNOPQRSTUVWXYZ1234567890";
    StringBuilder salt = new StringBuilder();
    Random rnd = new Random();

    while (salt.length()<18) {
        int index= (int) (rnd.nextFloat()*SALTCHARS.length());
        salt.append(SALTCHARS.charAt(index));
    }
    String saltStr = salt.toString();
    return saltStr;
}
}
@Entity
public class Users implements UserDetails{

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(name = "username")
private String username;

@Column(name = "password")
private String password;
private String firstName;
private String lastName;

@Column(name = "email",nullable = false, updatable = false)
private String email;
private String phone;
private boolean enabled=true;

@OneToMany(mappedBy = "users", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JsonIgnore
private Set<UserRoles> userRoles = new HashSet<>();

public Set<UserRoles> getUserRoles() {
    return userRoles;
}

public void setUserRoles(Set<UserRoles> userRoles) {
    this.userRoles = userRoles;
}

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
    Set<GrantedAuthority> authorities = new HashSet<>();
    userRoles.forEach(ur->authorities.add(new Authority(ur.getRoles().getName())));
    return authorities;
}

@Override
public boolean isAccountNonExpired() {
    return false;
}

@Override
public boolean isAccountNonLocked() {
    return false;
}

@Override
public boolean isCredentialsNonExpired() {
    return false;
}

===========other getter setters===================
}
SecurityUtility.java

 @EnableWebSecurity
 @Configuration
 @EnableGlobalMethodSecurity(prePostEnabled = true)
 public class SecurityConfig extends WebSecurityConfigurerAdapter {


@Autowired
private UserSecurityService userSecurityService;

@Autowired
private BCryptPasswordEncoder passwordEncoder(){
    return SecurityUtility.passwordEncoder();
}

private static final String[] PUBLIC_MATCHERS={
        "/css/**",
        "/js/**",
        "/image/**",
        "/login",
        "/register",
        "/fonts/**",
        "/newUser",
        "/forgetPassword",
        "/"
};

@Override
protected void configure(HttpSecurity http) throws Exception{

    http
            .authorizeRequests().
            antMatchers(PUBLIC_MATCHERS).
            permitAll().anyRequest().authenticated();

    http
            .csrf().disable().cors().disable()
            .formLogin().failureUrl("/login?error")
            .loginPage("/login").permitAll()
            .defaultSuccessUrl("/")
            .and()
            .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .logoutSuccessUrl("/?logout").deleteCookies("remember-me").permitAll()
            .and()
            .rememberMe();
}

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
    auth.userDetailsService(userSecurityService).passwordEncoder(passwordEncoder());
}

}
@Service
public class UserSecurityService implements UserDetailsService {

@Autowired
private UserRepository userRepository;

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

    Users users = userRepository.findByUsername(username);
    if(users==null){
        throw new UsernameNotFoundException("Username not found");
    }
    return users;
}
}
@Component
public class SecurityUtility {
private static final String SALT = "salt"; // Salt should be protected carefully

@Bean
public static BCryptPasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder(12, new SecureRandom(SALT.getBytes()));
}

@Bean
public static String randomPassword() {
    String SALTCHARS = "ABCEFGHIJKLMNOPQRSTUVWXYZ1234567890";
    StringBuilder salt = new StringBuilder();
    Random rnd = new Random();

    while (salt.length()<18) {
        int index= (int) (rnd.nextFloat()*SALTCHARS.length());
        salt.append(SALTCHARS.charAt(index));
    }
    String saltStr = salt.toString();
    return saltStr;
}
}
@Entity
public class Users implements UserDetails{

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(name = "username")
private String username;

@Column(name = "password")
private String password;
private String firstName;
private String lastName;

@Column(name = "email",nullable = false, updatable = false)
private String email;
private String phone;
private boolean enabled=true;

@OneToMany(mappedBy = "users", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JsonIgnore
private Set<UserRoles> userRoles = new HashSet<>();

public Set<UserRoles> getUserRoles() {
    return userRoles;
}

public void setUserRoles(Set<UserRoles> userRoles) {
    this.userRoles = userRoles;
}

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
    Set<GrantedAuthority> authorities = new HashSet<>();
    userRoles.forEach(ur->authorities.add(new Authority(ur.getRoles().getName())));
    return authorities;
}

@Override
public boolean isAccountNonExpired() {
    return false;
}

@Override
public boolean isAccountNonLocked() {
    return false;
}

@Override
public boolean isCredentialsNonExpired() {
    return false;
}

===========other getter setters===================
}
@组件
公共类安全实用程序{
私有静态最终字符串SALT=“SALT”//应小心保护盐
@豆子
公共静态BCryptPasswordEncoder passwordEncoder(){
返回新的BCryptPasswordEncoder(12,新的SecureRandom(SALT.getBytes());
}
@豆子
公共静态字符串密码(){
字符串SALTCHARS=“abcefghijklmnopqrstuvxyz1234567890”;
StringBuilder salt=新的StringBuilder();
随机rnd=新随机();

while(salt.length()在反复查看代码之后,我发现我在users.java类上犯了愚蠢的错误

 @Override
 public boolean isAccountNonExpired() {
 return false;
 }

 @Override
 public boolean isAccountNonLocked() {
 return false;
 }

 @Override
 public boolean isCredentialsNonExpired() {
 return false;
 }

这三段代码实际上应该返回true。在我的情况下,所有代码都返回false,这意味着我正在尝试登录非活动、过期和锁定的帐户。

在反复查看代码后,我发现我在users.java类上犯了愚蠢的错误

 @Override
 public boolean isAccountNonExpired() {
 return false;
 }

 @Override
 public boolean isAccountNonLocked() {
 return false;
 }

 @Override
 public boolean isCredentialsNonExpired() {
 return false;
 }
这三段代码实际上应该返回true。在我的情况下,所有代码都返回false,这意味着我正在尝试登录非活动、过期和锁定的帐户