我是 Java Spring 新手,我想创建一个用户注册系统,该系统存储在我的数据库(Postgres)中,其中密码由 BCryptPasswordEncoder 加密存储。注册过程工作正常,但当我想登录时,我总是收到“无效的用户名或密码”。信息。我已经到处搜索并阅读了很多文章,但我所做的一切都得到了相同的结果。
这是我的 SecurityConfiguration 类:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("customUserDetailsService")
private CustomUserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService()).and().authenticationProvider(authProvider());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/signin", "/confirm", "/error","/signup", "/css/**","/js/**","/images/**").permitAll()
.antMatchers("/admin/**").hasAuthority("ROLE_ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/signin")
.usernameParameter("username").passwordParameter("password")
.defaultSuccessUrl("/cockpit.html")
.permitAll()
.and()
.exceptionHandling().accessDeniedPage("/403")
.and()
.csrf()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/signin").and().exceptionHandling()
.accessDeniedPage("/error");
}
@Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
@Bean
public DaoAuthenticationProvider authProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(encoder());
return authProvider;
}
}
这是我的 CustomUserDetailsService 类:
@Service("customUserDetailsService")
public class CustomUserDetailsService implements UserDetailsService{
private final UserRepository userRepository;
private final RoleRepository userRolesRepository;
@Autowired
private PasswordEncoder bCryptPasswordEncoder;
@Autowired
public CustomUserDetailsService(UserRepository userRepository,RoleRepository userRolesRepository) {
this.userRepository = userRepository;
this.userRolesRepository=userRolesRepository;
}
@Override
public UserDetails loadUserByUsername(String username) throws
UsernameNotFoundException {
Logger LOGGER = Logger.getLogger(CustomUserDetailsService.class.getName());
User user = userRepository.findByUsername(username);
if (null == user) {
return null;
} else {
List<GrantedAuthority> authorities =
buildUserAuthority(userRolesRepository.findRoleByUserName(username));
LOGGER.info("Loaded account: " + user.getUsername() + " password: " + user.getPassword() + " password matches: " + bCryptPasswordEncoder.matches("password", user.getPassword()));
org.springframework.security.core.userdetails.User userDetails = new org.springframework.security.core.userdetails.User(user.getUsername(), Deuser.getPassword(),authorities);
return userDetails;
}
}
private List<GrantedAuthority> buildUserAuthority(Set<Role> userRoles) {
Set<GrantedAuthority> setAuths = new HashSet<>();
// add user's authorities
for (Role userRole : userRoles) {
setAuths.add(new SimpleGrantedAuthority(userRole.getRole()));
}
return new ArrayList<>(setAuths);
}
public User findByConfirmationToken(String confirmationToken) {
return userRepository.findByConfirmationToken(confirmationToken);
}
public void saveUser(User user){
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
userRepository.save(user);
}
public void saveRole(User user) {
Role role = new Role();
role.setRole("ROLE_USER");
role.setId(user.getId());
role.setUsername(user.getUsername());
userRolesRepository.save(role);
}
}
我在注册期间调用方法 saveUser(user) 和 saveRole(user) 。 LOGGER.info 消息为 bCryptPasswordEncoder.matches("password", user.getPassword()) 提供了“false”,即使我写了正确的密码。
已解决 好吧,我刚刚发现哪里错了。我在注册期间调用了两次 saveUser 方法,然后在激活期间调用了两次方法,因此密码被加密了两次。我通过添加方法 updateUser 而不使用加密解决了这个问题。
感谢您的帮助。
最佳答案
尝试这样:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// Create a default account
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
自定义用户详细信息:
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User account = userDao.getUserByUsername(username);
System.out.println("User got from DB----------------------" + account.getPassword());
boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
User user = new User(account.getUserName(), account.getPassword(), enabled, accountNonExpired,
credentialsNonExpired, accountNonLocked, getAuthorities(account.getRole()));
System.out.println(user.getPassword());
return user;
}
关于java - Spring Security 和 BCryptPasswordEncoder 用于注册和登录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47158112/