SpringSecurity Section 3 : Defining InMemory User

https://github.com/eazybytes/spring-security/blob/4.x.x/section3/springsecsection3/src/main/java/com/eazybytes/config/ProjectSecurityConfig.java

@Configuration public class ProjectSecurityConfig { @Bean SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests((requests) -> requests .requestMatchers("/myAccount", "/myBalance", "/myLoans", "/myCards").authenticated() .requestMatchers("/notices", "/contact", "/error").permitAll()); http.formLogin(withDefaults()); http.httpBasic(withDefaults()); return http.build(); } @Bean public UserDetailsService userDetailsService() { UserDetails user = User.withUsername("user").password("{noop}EazyBytes@12345").authorities("read").build(); UserDetails admin = User.withUsername("admin") .password("{bcrypt}$2a$12$88.f6upbBvy0okEa7OfHFuorV29qeK.sVbB9VQ6J6dWM1bW6Qef8m") .authorities("admin").build(); return new InMemoryUserDetailsManager(user, admin); } @Bean public PasswordEncoder passwordEncoder() { return PasswordEncoderFactories.createDelegatingPasswordEncoder(); } /** * From Spring Security 6.3 version * @return */ @Bean public CompromisedPasswordChecker compromisedPasswordChecker() { return new HaveIBeenPwnedRestApiPasswordChecker(); } }










please note UserDetailsService is an interface. UserDetailsManager is another interface that extends this interface. It has methods like 

  • createUser
  • deleteUser
  • updateUser
  • changePassword
the above interface has two class implementations
  • InMemoryUserDetailsManager
  • JDBCDetailsManager

In Spring Boot Security, {noop} is a password prefix used to specify that the password is in plain text and should not be encoded. The NoOpPasswordEncoder is a deprecated class that performs no hashing, making it highly insecure and strictly for testing or legacy systems only. 
Usage and Implementation
You can configure Spring Security to use the NoOpPasswordEncoder in a few ways: 
  • Using the {noop} Prefix (Recommended Testing Approach): The standard and most common way to use plain-text passwords for testing is to prefix the password string with {noop}. Spring's default DelegatingPasswordEncoder recognizes this prefix and handles the comparison correctly.
    java
    import org.springframework.security.core.userdetails.User;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.provisioning.InMemoryUserDetailsManager;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class SecurityConfig {
    
        @Bean
        public InMemoryUserDetailsManager userDetailsService() {
            UserDetails user = User.withUsername("user")
                .password("{noop}password") // The {noop} prefix tells Spring to use NoOpPasswordEncoder
                .roles("USER")
                .build();
            return new InMemoryUserDetailsManager(user);
        }
    }
    
  • Declaring a NoOpPasswordEncoder Bean (Not Recommended): You can explicitly create a NoOpPasswordEncoder bean, though this is discouraged due to its deprecated status.
    java
    import org.springframework.security.crypto.password.NoOpPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class MyAppConfig {
        @Bean
        public PasswordEncoder getPasswordEncoder() {
            return NoOpPasswordEncoder.getInstance(); // Uses the singleton instance
        }
    }
    
     
Key Considerations
  • Insecure for Production: Passwords stored or transmitted in plain text are vulnerable to security breaches.
  • Deprecated: The NoOpPasswordEncoder class itself is marked as @Deprecated in the Spring Security API documentation to emphasize its insecurity.
  • Modern Alternatives: Spring highly recommends using adaptive one-way encoding functions like BCryptPasswordEncoderPbkdf2PasswordEncoder, or SCryptPasswordEncoder for production environments. The default DelegatingPasswordEncoder supports all these options and handles password upgrades seamlessly

Password Encoder

https://stackoverflow.com/questions/46999940/spring-boot-how-to-specify-the-passwordencoder

https://spring.io/blog/2017/11/01/spring-security-5-0-0-rc1-released#password-encoding

https://medium.com/@nishanthp155/spring-security-password-encoders-with-hashing-103008534e8d

inside a @configuration bean, add 

@Bean public PasswordEncoder passwordEncoder() { return PasswordEncoderFactories.createDelegatingPasswordEncoder(); }

https://bcrypt-generator.com/

see line number 35 for BCrypt https://github.com/eazybytes/spring-security/blob/4.x.x/section3/springsecsection3/src/main/java/com/eazybytes/config/ProjectSecurityConfig.java

Compromised Password Checker

@Bean public CompromisedPasswordChecker compromisedPasswordChecker() { return new HaveIBeenPwnedRestApiPasswordChecker(); }

this calls a standard API

in END this API simply returns a boolean , if this password has been leaked or not.









you get above error when you register user , hence inforcing strong password

LEFT deep dive videos

ok





















Comments

Popular posts from this blog

Agentic AI Course : Week 1

LLM Engineering course : Day 1

LLM Engineering : Week 2