[[servlet-authentication-inmemory]] = In-Memory Authentication Spring Security's `InMemoryUserDetailsManager` implements <> to provide support for username/password based authentication that is stored in memory. `InMemoryUserDetailsManager` provides management of `UserDetails` by implementing the `UserDetailsManager` interface. `UserDetails` based authentication is used by Spring Security when it is configured to <> for authentication. In this sample we use <> to encode the password of `password` and get the encoded password of `+{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW+`. .InMemoryUserDetailsManager Java Configuration ==== .Java [source,java,role="primary",attrs="-attributes"] ---- @Bean public UserDetailsService users() { UserDetails user = User.builder() .username("user") .password("{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW") .roles("USER") .build(); UserDetails admin = User.builder() .username("admin") .password("{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW") .roles("USER", "ADMIN") .build(); return new InMemoryUserDetailsManager(user, admin); } ---- .XML [source,xml,role="secondary",attrs="-attributes"] ---- ---- .Kotlin [source,kotlin,role="secondary",attrs="-attributes"] ---- @Bean fun users(): UserDetailsService { val user = User.builder() .username("user") .password("{bcrypt}$2a$10\$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW") .roles("USER") .build() val admin = User.builder() .username("admin") .password("{bcrypt}$2a$10\$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW") .roles("USER", "ADMIN") .build() return InMemoryUserDetailsManager(user, admin) } ---- ==== The samples above store the passwords in a secure format, but leave a lot to be desired in terms of getting started experience. In the sample below we leverage <> to ensure that the password stored in memory is protected. However, it does not protect against obtaining the password by decompiling the source code. For this reason, `User.withDefaultPasswordEncoder` should only be used for "getting started" and is not intended for production. .InMemoryUserDetailsManager with User.withDefaultPasswordEncoder ==== .Java [source,java,role="primary"] ---- @Bean public UserDetailsService users() { // The builder will ensure the passwords are encoded before saving in memory UserBuilder users = User.withDefaultPasswordEncoder(); UserDetails user = users .username("user") .password("password") .roles("USER") .build(); UserDetails admin = users .username("admin") .password("password") .roles("USER", "ADMIN") .build(); return new InMemoryUserDetailsManager(user, admin); } ---- .Kotlin [source,kotlin,role="secondary"] ---- @Bean fun users(): UserDetailsService { // The builder will ensure the passwords are encoded before saving in memory val users = User.withDefaultPasswordEncoder() val user = users .username("user") .password("password") .roles("USER") .build() val admin = users .username("admin") .password("password") .roles("USER", "ADMIN") .build() return InMemoryUserDetailsManager(user, admin) } ---- ==== There is no simple way to use `User.withDefaultPasswordEncoder` with XML based configuration. For demos or just getting started, you can choose to prefix the password with `+{noop}+` to indicate <>. . `+{noop}+` XML Configuration ==== [source,xml,attrs="-attributes"] ---- ---- ====