我是Spring的新手,我正在尝试在项目中实现spring安全性。我可以使用Bcrypt使用哈希密码创建用户,但是每当我尝试使用相同的密码登录时,它都会失败。我还尝试检查其他SO答案(如Spring Security BCryptPasswordEncoder Inserted But Not Match)无法解决所遇到的问题。
以下是到目前为止的尝试
WebSecurityConfigurerAdapter类
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// TODO Auto-generated method stub
http.csrf().disable();
http.authorizeRequests().antMatchers("/login", "/app-assets/**", "/assets/**").permitAll();
http.authorizeRequests().antMatchers("/add-user", "/users-list").hasRole("ADMIN");
http.authorizeRequests().antMatchers("/", "/index", "/add-content", "/mange-content").hasAnyRole("ADMIN", "USER");
http
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/index")
.failureUrl("/login?error=true")
.usernameParameter("username")
.passwordParameter("password")
//.failureUrl("/login-error.html")
.and()
.logout()
.invalidateHttpSession(true)
.clearAuthentication(true)
.logoutSuccessUrl("/login?logout")
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.permitAll();
}
@Bean
public DaoAuthenticationProvider authProvider() {
System.out.println("GOT CALLED HERE.....");
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// TODO Auto-generated method stub
//auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
auth.authenticationProvider(authProvider());
}
}
UserDetailsService
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserDAO userDAO;
@Autowired
private RoleDAO roleDAO;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userDAO.findUserByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User "+username+"not fount");
}
List<String> roleNames = roleDAO.getRoleNames(user.getAdminId());
System.out.println("USERNAME: "+user.getAdminId() + " "+user.getPassword());
List<GrantedAuthority> grantList = new ArrayList<GrantedAuthority>();
if (roleNames != null) {
for (String role : roleNames) {
GrantedAuthority authority = new SimpleGrantedAuthority(role);
grantList.add(authority);
}
}
UserDetails userDetails = (UserDetails) new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), grantList);
return userDetails;
}
}
测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
@Autowired
private UserDAO userDAO;
@Autowired
private BCryptPasswordEncoder encoder;
@Test
public void contextLoads() {
String password = "eureka";
String encrytedPassword = encoder.encode(password);
User user = userDAO.findUserByEmail("xxx@gmail.com");
System.out.println(encrytedPassword);
System.out.println("Matched: " + encoder.matches("eureka", encrytedPassword));//This line returns true
assertEquals(encrytedPassword, user.getPassword());
}
}
我也尝试了重写matchs()但无济于事
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder() {
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
// This throws an error
return matches(rawPassword, encodedPassword);
}
};
}
注意:哈希密码和原始密码是从matchs()方法获得的。因此,从数据库中检索哈希密码没有问题。