In-Memory Users

UserDetails and UserDetailsService

Spring Security does not care where users are stored. It asks one interface:

public interface UserDetailsService {
    UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}

UserDetails is Spring's view of a user: getUsername(), getPassword() (the hash), getAuthorities(), and flags such as isEnabled() and isAccountNonLocked().

Users in Memory

For demos, tests and tiny internal tools, define users in code with InMemoryUserDetailsManager:

@Configuration
public class UserConfig {

    @Bean
    UserDetailsService userDetailsService(PasswordEncoder encoder) {
        UserDetails asha = User.withUsername("asha")
                .password(encoder.encode("asha123"))
                .roles("CUSTOMER")                 // stored as authority ROLE_CUSTOMER
                .build();
        UserDetails ravi = User.withUsername("ravi")
                .password(encoder.encode("ravi123"))
                .roles("CUSTOMER", "ADMIN")
                .build();
        return new InMemoryUserDetailsManager(asha, ravi);
    }

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

Note: Declaring your own UserDetailsService bean switches off the generated user / random password from the starter.

Limitations

  • Users disappear on restart and new users cannot sign up.
  • Passwords live in source code (even if encoded at startup).
  • Fine for: learning, integration tests, a one-person admin tool. Real apps use a database (next topics).

Try It

curl -s -o /dev/null -w "%{http_code}\n" -u ravi:ravi123 localhost:8080/api/cart
curl -s -o /dev/null -w "%{http_code}\n" -u ravi:wrong   localhost:8080/api/cart

Example output

200
401