The UserDetailsService is a core interface that defines how to retrieve user information. It provides an abstraction layer over different user identity stores.
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
๐ฏ Primary Purpose
Provides a standard way to load user-specific data during authentication. It's the bridge between Spring Security and your user data source.
๐ Data Source Abstraction
Can load users from databases, LDAP, memory, web services, or any custom source. Implementation details are hidden behind this interface.
๐ UserDetails Contract
Returns UserDetails object containing username, password, authorities, and account status flags (enabled, expired, locked).
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
// Fetch user from database
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException(
"User not found: " + username));
// Convert to Spring Security UserDetails
return org.springframework.security.core.userdetails.User.builder()
.username(user.getUsername())
.password(user.getPassword())
.authorities(user.getRoles().stream()
.map(role -> new SimpleGrantedAuthority("ROLE_" + role.getName()))
.collect(Collectors.toList()))
.accountExpired(!user.isAccountNonExpired())
.accountLocked(!user.isAccountNonLocked())
.credentialsExpired(!user.isCredentialsNonExpired())
.disabled(!user.isEnabled())
.build();
}
}
// Custom UserDetails implementation
public class CustomUserDetails implements UserDetails {
private String username;
private String password;
private List<GrantedAuthority> authorities;
private boolean enabled;
private boolean accountNonExpired;
private boolean credentialsNonExpired;
private boolean accountNonLocked;
// Constructor and getters...
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public boolean isEnabled() {
return enabled;
}
// Other UserDetails methods...
}