Java Spring Security - User.withDefaultPasswordEncoder() is deprecated?

18,678

Solution 1

EDIT: deleted old answer, misunderstood the question. Here's the new one:

User.withDefaultPasswordEncoder() can still be used for demos, you don't have to worry if that's what you're doing - even if it's deprecated - but in production, you shouldn't have a plain text password in your source code.

What you should be doing instead of using your current userDetailsService() method is the following:

private static final String ENCODED_PASSWORD = "$2a$10$AIUufK8g6EFhBcumRRV2L.AQNz3Bjp7oDQVFiO5JJMBFZQ6x2/R/2";


@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
        .passwordEncoder(passwordEncoder())
        .withUser("user").password(ENCODED_PASSWORD).roles("USER");
}


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

Where ENCODED_PASSWORD is secret123 encoded with BCrypt. You can also encode it programmatically like so: passwordEncoder().encode("secret123").

That way, even if you push your code to a public repository, people won't know the password because ENCODED_PASSWORD only shows the encoded version of the password and not the plain text version, but because you know that $2a$10$AIUufK8g6EFhBcumRRV2L.AQNz3Bjp7oDQVFiO5JJMBFZQ6x2/R/2 is actually the encoded password of the string secret123 whereas others don't, your in-memory user with the credentials user:secret123 won't be compromised.

Note that I'm using leaving it in a static variable for the sake of the example.

Solution 2

Using the passwordEncoder.encode() would be like this

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

   @Override
   protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
    .passwordEncoder(passwordEncoder())
    .withUser("user")
    .password(passwordEncoder().encode("miClave"))
    .roles("USER");
   }

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

}
Share:
18,678

Related videos on Youtube

sammyjjohnson71
Author by

sammyjjohnson71

Updated on October 06, 2022

Comments

  • sammyjjohnson71
    sammyjjohnson71 over 1 year

    I am very new to java spring security, and was following the Spring.io tutorial guide. As part of this, I edited the WebSecurityConfig class as required:

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
          http
            .authorizeRequests()
                .antMatchers("/", "/home").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
        }
    
        @Bean
        @Override
        public UserDetailsService userDetailsService() {
            UserDetails user =
             User.withDefaultPasswordEncoder()
                .username("user")
                .password("password")
                .roles("USER")
                .build();
    
        return new InMemoryUserDetailsManager(user);
        }
    }
    

    Within the userDetailService() method, it uses withDefaultPasswordEncoder() which is now deprecated as seen in the docs: withDefaultPasswordEncoder()

    Unfortunately, I have not been able to find an alternative to this, to complete this tutorial without using the deprecated method. Would somebody be able to provide an alternative for this if possible?

    Thanks!

    note: I have attached a couple of screen shots of my error, as well as my gradle file

    image 1: The error I am receiving

    image 2: My gradle file

    • chrylis -cautiouslyoptimistic-
      chrylis -cautiouslyoptimistic- about 6 years
      Did you read the whole Javadoc? It goes into substantial detail, especially including "is acceptable for demos and getting started".
  • Scaramouche
    Scaramouche over 5 years
    Hi, please a quick question about the passwordEncoder().encode("secret123") suggestion. You said That way, even if you push your code to a public repository, people won't know the password because ENCODED_PASSWORD only shows the encoded version of the password and not the plain text version, I'm confused, if I use passwordEncoder().encode("secret123") and upload it to a repository, wouldn't people see my password? whereas if I stick to your original code using ENCODED_PASSWORD variable, that way people won't see my raw password. I'm confused about what you meant by That way,... thanx
  • TwiN
    TwiN over 5 years
    @Scaramouche It's never a good idea to push your password on a public repository no matter if it's encoded/hashed or not, but the point is, if you, instead of writing passwordEncoder().encode("secret123") in your code, you pushed $2a$10$AIUufK8g6EFhBcumRRV2L.AQNz3Bjp7oDQVFiO5JJMBFZQ6x2/R/2‌​, people wouldn't automatically know that your password is secret123 because you just pushed the hash -- not the actual password. The point I was trying to make was that you could run System.out.println(passwordEncoder().encode("secret123")) locally, copy the result and use that result as password
  • TwiN
    TwiN over 5 years
    ... in your code. But once again, keep in mind that all I'm saying is that pushing $2a$10$AIUufK8g6EFhBcumRRV2L.AQNz3Bjp7oDQVFiO5JJMBFZQ6x2/R/2 is much more secure than pushing passwordEncoder().encode("secret123") if you want to keep your password hidden, but in the future, when there are better and faster computers, it's very likely for your password to be compromised. It's better to avoid pushing any password/confidential information on a public repository. Instead, you should use environment variables.
  • InterestedDev
    InterestedDev over 5 years
    @Twin How can I handle successful authentication? For example, I need to generate a GWT token and return and add it to HTTP Request as a new Header. Is it possible?
  • Mayank Aggarwal
    Mayank Aggarwal over 3 years
    @TwiN I followed your approach. However, I keep getting "Bad credentials" message on supplying username as "user" and password as "secret123". Can you please help on why this error is seen?