spring-projects / spring-security

Spring Security
http://spring.io/projects/spring-security
Apache License 2.0
8.81k stars 5.9k forks source link

Discrepancy in spring security tutorial concerning how bcrypt password strings structure looks like #15466

Closed owolabiezekiel closed 3 months ago

owolabiezekiel commented 3 months ago

Expected Behavior

The tutorials say that when a password is encrypted with the bcrypt password encoder, the encoded strings begin with a string {bcrypt} but that has never been the case in my relatively short Spring career.

Current Behavior

When a string encoded with the bcrypt password encoder gets saved in the database, it doesn't have the string {bcrypt} appended to it. At least in all the projects I have done where I have used the bcrypt password encoder, I have never seen the string {bcrypt} appended to the hashed password

Context Maybe the tutorials are old. I have been reading the spring security docs extensively for 2 days now and I see that when they talk about bcrypt password encoding, they usually state that the encoded string usually starts with the string {bcrypt} but when I check my own database, this isn't the case.

I know this doesn't affect anything but the docs can be clearer. If it is possible, I can try to go through the whole docs and make the corrections to the best of my ability and submit a PR. Also if there is something that I am missing, then maybe it can be made clearer in the documentation

dalbani commented 3 months ago

I do see the {bcrypt} prefix in my case, e.g. for a dummy user:

# select * from users;
         username         |                               password                               | enabled 
--------------------------+----------------------------------------------------------------------+---------
 lIB98D2EChzVarM5JQDSxLt1 | {bcrypt}$2a$10$acCYP92YTQ7KI49Thbt7ZO5q01W4zMsWZIYLMK3gqwtdG0aNzeuDO | t

For the record, this is how my app is configured:

    @Bean
    public JdbcUserDetailsManager users(DataSource dataSource) {
        JdbcUserDetailsManager jdbcUserDetailsManager = new JdbcUserDetailsManager(dataSource);
        jdbcUserDetailsManager.setEnableGroups(true);
        return jdbcUserDetailsManager;
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }
owolabiezekiel commented 3 months ago

Somehow, mine is not similar at all. My configuration is

@Bean
  public PasswordEncoder encoder() {
    return new BCryptPasswordEncoder();
  }

  public AuthenticationProvider authenticationProvider() {
    DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
    authProvider.setUserDetailsService(userDetailsService);
    authProvider.setPasswordEncoder(passwordEncoder);
    return authProvider;
  } 

but it does start with the $2a$ string which is part of the signature for a bcrypt encoded string

dalbani commented 3 months ago

If I'm not mistaken, it's the logic in DelegatingPasswordEncoder that uses prefixes like {bcrypt} to differentiate hashing algorithms.

owolabiezekiel commented 3 months ago

Okay, I will look through it then. If I find that this is the case, then I will close this issue. Thank you @dalbani

jzheaux commented 3 months ago

@owolabiezekiel and @dalbani, you are correct that DelegatingPasswordEncoder adds the prefix.

The tutorials say

Are these tutorials from Spring Security? For example, spring-security-samples or one of the Spring Guides? If not, I don't think there's anything for us to do here.

owolabiezekiel commented 3 months ago

The tutorials are from spring security docs here

I see where the supposed discrepancy is coming from now. I will now go ahead to close this issue. Thank you @dalbani @jzheaux