Description this may looks weird but it's a serious issue i encountered while working on a spring web project project, i used this code to encode a BCryptPassword because according to the following stackoverflow answer BCryptPasswordEncoder fails to match a raw password with an encoded password. because The hashed password might be “$2b” or “$2y” And there is a bug in Spring Security that has a regex always looking for “$2a” so i can generate an encoded password with "2$a"
String generatedPassword = passwordEncoder.encode("user");
System.out.println(generatedPassword);
output example for password = user :
$2a$10$k6N93VrpEJrjizgr3tLJueiPl87.HSQ41S1TZfXAwQefq30D9SkHq
you can try checking this with String. now when i copy the encoded password outputted by this code to my user password field in my database it wont login after checking and i tried many times only one attempt worked fine and all others failed. one solution i found is using this website to generate the encoded password and the problem was resolved and i was able to make a login with every string generated from this external website.
WebSecurityConfig.java
``` package com.centredeformation.main.security;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private DataSource dataSource; @Override protected void configure(HttpSecurity http) throws Exception { http.headers().contentTypeOptions().disable(); http.csrf().disable();// Prevent cross-site request forgery http.authorizeRequests().antMatchers("/login", "/build/","/dist/","/plugins/**").permitAll().antMatchers("/pointage").hasRole("ADMIN").anyRequest().authenticated().and() .formLogin() .loginPage("/login").permitAll().defaultSuccessUrl("/dashbord", true) .and().logout().permitAll();
// The X-Content-Type-Options header setting promises to load static resources
// X-Content-Type-Options header settings promise to load static resources
http.headers().frameOptions().sameOrigin();
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String generatedPassword = passwordEncoder.encode("aymen");
System.out.println(generatedPassword);
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery("select username,password,enabled from users where username=?")
.authoritiesByUsernameQuery("select username,authority from authorities where username=?");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
- I'm using spring boot 2.5.1
- Spring Security 5.5.1
I think the problem is not in the generated values because they all matches the corresponding password i suspect that this issue is related the the checking function( not to be confused with _BCryptPasswordEncoder().matches_ because it can't check it's own generated String but it can't check other generated values when submitting the login
**Comment From: eleftherias**
Thanks for reaching out @aymenBox.
I tried using the encoded password you supplied ($2a$10$k6N93VrpEJrjizgr3tLJueiPl87.HSQ41S1TZfXAwQefq30D9SkHq) and I was able to log in successfully with the credentials user / user.
I used the below configuration:
```java
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public InMemoryUserDetailsManager userDetailsService() {
UserDetails user = User.withUsername("user")
.password("$2a$10$k6N93VrpEJrjizgr3tLJueiPl87.HSQ41S1TZfXAwQefq30D9SkHq")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
Could you explain in more detail what your scenario is? Does the above configuration work for you?
Comment From: spring-projects-issues
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Comment From: aymenBox
hello @eleftherias actually the password hash as i described is not saved in Memory it's in the database that's were i notice the issues try creating a user class and a database with a user and role table in it and fill the password field of the user table with the one i provided witch are the same that was generated with spring boot and see if it works again the problem i found when i try to decode the password from the database not from the memory .
Comment From: eleftherias
@aymenBox What kind of database are you using? Do you have a sample that reproduces the issue?
Comment From: spring-projects-issues
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Comment From: spring-projects-issues
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.
Comment From: hexwit
I have the same issue. Database postgres 14 (docker).