Is there a way to configure password encoder for default spring security password

skywalker

I use overridden values for spring security username and password. Following properties are in my

application.properties
spring.security.user.name=myUser
spring.security.user.password=myPassword
spring.security.user.roles=admin

I would like to encrypt the password value as follows:

spring.security.user.name=myUser
spring.security.user.password={bcrypt}hashedpassword valuevalue
spring.security.user.roles=admin

I added PasswordEncoder in my SpringConfig:

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

In some example I noticed that there is for AuthenitcationManagerBuilder but I do not know what datasource should be used. What else do I need to use encrypted password for default user?

@Autowired
public void configAuthentication(AuthenticationManagerBuilder auth) 
        throws Exception {

Adding my spring security config as a reference:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf()
            .disable()
            .authorizeRequests().antMatchers("/api/v1/custom").hasRole("admin")
            .anyRequest()
            .authenticated()
            .and()
            .httpBasic();

        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

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

Grabbing:

$2a$12$7Bg57uTtN7GWIdiqRW4h5e/aOUFagHwkEGv9byUr0bb/QbUU8S4rS

for input:

hello

... from (e.g. thx): https://bcrypt-generator.com/

With:

  • spring-starter (web, security),
  • application.properties:
    spring.security.user.password={bcrypt}$2a$12$7Bg57uTtN7GWIdiqRW4h5e/aOUFagHwkEGv9byUr0bb/QbUU8S4rS
    
  • and any (rest)controller:
    package com.example.demo;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.Bean;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @SpringBootApplication
    @RestController
    public class DemoApplication {
    
       public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
       }
    
       //  @Bean
       //  public PasswordEncoder encoder() {
       //   return new BCryptPasswordEncoder();
       //  }
    
       @GetMapping("secured")
       public String secured() {
        return "Hello Admin";
       }
    }
    
  • and without additional config,
  • we can login with user=user and password=hello.

Adding:

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

breaks this behavior!! To "fix it", we can (application.properties):

spring.security.user.password=$2a$12$7Bg57uTtN7GWIdiqRW4h5e/aOUFagHwkEGv9byUr0bb/QbUU8S4rS

.. omit the "tag" {bcrypt}! ...

Responsible for "tags"/capable of several algorithms is the DelegatingPasswordEncoder, which is auto configured (via [AuthenticationConfiguration|HttpSecurityConfiguration].LazyPasswordEncoder ..if no other PasswordEncoder bean found) and uses PasswordEncoderFactories behind the scenes, like (currently) this:

@SuppressWarnings("deprecation")
public static PasswordEncoder createDelegatingPasswordEncoder() {
  String encodingId = "bcrypt";
  Map<String, PasswordEncoder> encoders = new HashMap<>();
  encoders.put(encodingId, new BCryptPasswordEncoder());
  encoders.put("ldap", new org.springframework.security.crypto.password.LdapShaPasswordEncoder());
  encoders.put("MD4", new org.springframework.security.crypto.password.Md4PasswordEncoder());
  encoders.put("MD5", new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("MD5"));
  encoders.put("noop", org.springframework.security.crypto.password.NoOpPasswordEncoder.getInstance());
  encoders.put("pbkdf2", Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_5());
  encoders.put("pbkdf2@SpringSecurity_v5_8", Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_8());
  encoders.put("scrypt", SCryptPasswordEncoder.defaultsForSpringSecurity_v4_1());
  encoders.put("scrypt@SpringSecurity_v5_8", SCryptPasswordEncoder.defaultsForSpringSecurity_v5_8());
  encoders.put("SHA-1", new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("SHA-1"));
  encoders.put("SHA-256",
          new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("SHA-256"));
  encoders.put("sha256", new org.springframework.security.crypto.password.StandardPasswordEncoder());
  encoders.put("argon2", Argon2PasswordEncoder.defaultsForSpringSecurity_v5_2());
  encoders.put("argon2@SpringSecurity_v5_8", Argon2PasswordEncoder.defaultsForSpringSecurity_v5_8());
  return new DelegatingPasswordEncoder(encodingId, encoders);
}

EDIT:

No, also introducing:

@Configuration
class WebSecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
      http
          .csrf()
          .disable()
          .authorizeHttpRequests().requestMatchers("/secured").hasRole("admin")
          .anyRequest()
          .authenticated()
          .and()
          .httpBasic();

      http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
      return http.build();
    }
  }
}

Plus:

spring.security.user.roles=admin

Doesn't change my observations:

  • When "custom password encoder"
  • and $2a$12$7Bg57uTtN7GWIdiqRW4h5e/aOUFagHwkEGv9byUr0bb/QbUU8S4rS
    • can login with user:hello (and view /secured response)
  • with default/-out password encoder
  • and {bcrypt}$2a$12$7Bg57uTtN7GWIdiqRW4h5e/aOUFagHwkEGv9byUr0bb/QbUU8S4rS
    • can login with user:hello (and view /secured response)

(it only switches from form to basic login:)

Test (good/app config):

package com.example.demo;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.unauthenticated;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@WebMvcTest
class WithAppConfigTest {

  @Autowired
  MockMvc mockMvc;

  @Test
  void expectAccess() throws Exception {
    mockMvc.perform(
        get("/secured")
            .with(httpBasic("user", "hello"))
    ).andExpectAll(
        authenticated(),
        status().isOk(),
        content().string("Hello Admin"));
  }

  @Test
  void expectUnauthorized() throws Exception {
    mockMvc.perform(
        get("/secured")
            .with(httpBasic("user", "wrong"))
    ).andExpectAll(
        unauthenticated(),
        status().isUnauthorized(),
        content().bytes(new byte[0]));
  }
}

Test forbidden:

@WebMvcTest(properties = "spring.security.user.roles=foo,bar,baz")
class WithFakeConfigTest {

  @Autowired
  MockMvc mockMvc;

  @Test
  void expectForbidden() throws Exception {
    mockMvc.perform(
        get("/secured")
            .with(httpBasic("user", "hello"))
    ).andExpectAll(
        authenticated(), // !, but:
        status().isForbidden(),
        content().bytes(new byte[0]));
  }
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Is there a way to configure password encoder for default password?

why spring security gives empty password to password encoder?

Remove "Using default security password" on Spring Boot

Spring Boot Rest Security Basic Auth Password Encoder does not encrypt password on login

Password Encoder/Decoder in Spring Boot

Spring Security : Encrypt password

Security of MySQL default password in Docker

Spring security_Password Encryption

Username Password Authentication in Spring Security

Spring Security 5.2 Password Flow

Spring security: get password in UserDetailsServiceMethod

Recover username and password with spring security

Password is not getting encoded in spring security

Change WooCommerce default password security level

Password Security

Spring Oauth2. Password encoder is not set in DaoAuthenticationProvider

How to use Spring security without password encoding?

Spring Security BASIC auth - matching password hash

Spring Security Basic Auth Password Rotation Issue

BCrypt: Empty Encoded Password with Spring Security

Read username/password from a file in Spring Security

Password encrypt and decrypt using Spring-security

Spring Security force logout when password change

spring security encode password with bcrypt algorithm

Correct way to invalidate all other http sessions for a user in Grails with Spring Security plugin on password change?

Is there a way to change the default login/password prompts?

Spring Security - Conceptual question around generated security password

Configure Lightdm (GTK) for last saved or a default user and focus on password?

Apache ISIS isis-module-security default user/password