| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 | [[servlet-authentication-inmemory]]= In-Memory AuthenticationSpring Security's `InMemoryUserDetailsManager` implements xref:servlet/authentication/passwords/user-details-service.adoc#servlet-authentication-userdetailsservice[UserDetailsService] 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 <<servlet-authentication-unpwd-input,accept a username and password>> for authentication.In the following sample, we use xref:features/authentication/password-storage.adoc#authentication-password-storage-boot-cli[Spring Boot CLI] to encode a password value 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"]----@Beanpublic 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"]----<user-service>	<user name="user"		password="{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW"		authorities="ROLE_USER" />	<user name="admin"		password="{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW"		authorities="ROLE_USER,ROLE_ADMIN" /></user-service>----.Kotlin[source,kotlin,role="secondary",attrs="-attributes"]----@Beanfun 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 preceding samples store the passwords in a secure format but leave a lot to be desired in terms of a getting started experience.In the following sample, we use xref:features/authentication/password-storage.adoc#authentication-password-storage-dep-getting-started[User.withDefaultPasswordEncoder] 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"]----@Beanpublic 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"]----@Beanfun 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 xref:features/authentication/password-storage.adoc#authentication-password-storage-dpe-format[no encoding should be used]:.<user-service> `+{noop}+` XML Configuration====[source,xml,attrs="-attributes"]----<user-service>	<user name="user"		password="{noop}password"		authorities="ROLE_USER" />	<user name="admin"		password="{noop}password"		authorities="ROLE_USER,ROLE_ADMIN" /></user-service>----====
 |