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
The first thing you need to do is add Spring Security to the classpath. The WebSecurityConfig class is annotated with @EnableWebSecurity to enable Spring Security's web security support and provide the Spring MVC integration.
You need to declare SecurityFilterChain and WebSecurityCustomizer beans instead of overriding methods of WebSecurityConfigurerAdapter class. NOTE: If you don't want to change your current code, you should keep Spring Boot version lower than 2.7. 0 or Spring Security version older than 5.7. 1.
Interface UserDetails. Provides core user information. Implementations are not used directly by Spring Security for security purposes. They simply store user information which is later encapsulated into Authentication objects.
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.
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(); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With