Customize UserDetailsRepository¶
The authentication manager resolves users through a ReactiveUserDetailsService, whose single method returns a Mono<UserDetails>. The in-memory MapReactiveUserDetailsService covers demos; this page shows two ways to replace it.
Load users from a properties file¶
Spring Security provides a ReactiveUserDetailsServiceResourceFactoryBean which loads users from a properties file and creates the ReactiveUserDetailsService for your applications:
@Bean
public ReactiveUserDetailsServiceResourceFactoryBean userDetailsService() {
return ReactiveUserDetailsServiceResourceFactoryBean
.fromResourceLocation("classpath:users.properties");
}
The content of the users.properties file is similar to the following:
The key is the username; the value is the password and its roles.
You can explore the sample in spring-reactive-sample/security-user-properties
Load users from a database¶
For real applications, implement the ReactiveUserDetailsService against your user store. Using Mongo as the backend store, create a User document class that implements the Spring Security UserDetails interface:
@Data
@ToString
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Document
class User implements UserDetails {
@Id
private String id;
private String username;
private String password;
@Builder.Default()
private boolean active = true;
@Builder.Default()
private List<String> roles = new ArrayList<>();
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return AuthorityUtils.createAuthorityList(roles.toArray(new String[roles.size()]));
}
@Override
public boolean isAccountNonExpired() {
return active;
}
@Override
public boolean isAccountNonLocked() {
return active;
}
@Override
public boolean isCredentialsNonExpired() {
return active;
}
@Override
public boolean isEnabled() {
return active;
}
}
Create a UserRepository for User:
public interface UserRepository extends ReactiveMongoRepository<User, String> {
Mono<User> findByUsername(String username);
}
Replace the in-memory user details service bean with the following, which connects to the real database:
@Bean
public ReactiveUserDetailsService userDetailsService(UserRepository users) {
return (username) -> users.findByUsername(username).cast(UserDetails.class);
}
The security-data-mongo sample goes one step further and registers a PasswordEncoder:
@Bean
PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
You can explore the sample in spring-reactive-sample/security-data-mongo.