123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- [[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/password] for authentication.
- In this sample we use xref:features/authentication/password-storage.adoc#authentication-password-storage-boot-cli[Spring Boot CLI] to encode the password 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 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 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>
- ----
|