en Peris
en Peris

Reputation: 1717

AuthenticationManagerBuilder in SpringBoot 2.0.1.RELEASE

I have a SpringBoot 2.0.1.RELEASE mvc application, so in the security config I've defined this method:

@Autowired
 public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
            auth
                    .inMemoryAuthentication()
                    .withUser(User
                            .withDefaultPasswordEncoder()
                            .username(DEV_USER)
                            .password(DEV_PWD)
                            .roles("ADMIN").build());
        }

but It seems that The method withDefaultPasswordEncoder() from the type User is deprecated but I don't know which I have to use instead,

Upvotes: 2

Views: 3552

Answers (1)

Unknown
Unknown

Reputation: 2137

From the Spring Framework Doc

@Deprecated
public static User.UserBuilder withDefaultPasswordEncoder()

Deprecated. Using this method is not considered safe for production, but is acceptable for demos and getting started. For production purposes, ensure the password is encoded externally. See the method Javadoc for additional details.

WARNING: This method is considered unsafe for production and is only intended for sample applications.

UserDetails user = User.withDefaultPasswordEncoder()
     .username("user")
     .password("password")
     .roles("USER")
     .build();
 // outputs {bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG
 System.out.println(user.getPassword());

This is not safe for production (it is intended for getting started experience) because the password "password" is compiled into the source code and then is included in memory at the time of creation. This means there are still ways to recover the plain text password making it unsafe. It does provide a slight improvement to using plain text passwords since the UserDetails password is securely hashed. This means if the UserDetails password is accidentally exposed, the password is securely stored. In a production setting, it is recommended to hash the password ahead of time. For example:

PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
 // outputs {bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG
 // remember the password that is printed out and use in the next step
 System.out.println(encoder.encode("password"));



UserDetails user = User.withUsername("user")
     .password("{bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG")
     .roles("USER")
     .build();

Returns: a UserBuilder that automatically encodes the password with the default PasswordEncoder

To answer your question, you can do :

public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        UserDetails userDetails = User.withUsername(DEV_USER)
                 .password(encoder.encode(DEV_PWD))
                 .roles("ADMIN")
                 .build();
        auth.inMemoryAuthentication().withUser(userDetails);
    }

Upvotes: 5

Related Questions