spring security可以';即使凭据正确,也无法登录
即使在登录表单上提供了正确的凭据,我也无法登录 login.htmlspring 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">
<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,这意味着我正在尝试登录非活动、过期和锁定的帐户