| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 | 
							- [[servlet-authentication-inmemory]]
 
- = In-Memory Authentication
 
- Spring 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 xref:servlet/authentication/passwords/index.adoc#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
 
- [tabs]
 
- ======
 
- 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"]
 
- ----
 
- <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"]
 
- ----
 
- @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 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
 
- [tabs]
 
- ======
 
- 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 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>
 
- ----
 
 
  |