0
0
SpringbootHow-ToBeginner · 4 min read

How to Use UserDetailsService in Spring Boot for Authentication

In Spring Boot, UserDetailsService is used to load user-specific data during authentication. You implement its loadUserByUsername method to fetch user details from your data source, then configure Spring Security to use your custom service for authentication.
📐

Syntax

The UserDetailsService interface has one main method:

  • loadUserByUsername(String username): Loads user data by username and returns a UserDetails object.

You implement this interface to tell Spring Security how to find your users.

java
public interface UserDetailsService {
    UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}
💻

Example

This example shows a simple custom UserDetailsService implementation that loads a user from a hardcoded list and configures Spring Security to use it.

java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

    @Bean
    public UserDetailsService userDetailsService() {
        return new UserDetailsService() {
            @Override
            public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
                if ("user".equals(username)) {
                    return User.withUsername("user")
                            .password("{noop}password")
                            .roles("USER")
                            .build();
                } else {
                    throw new UsernameNotFoundException("User not found");
                }
            }
        };
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
            .httpBasic();
        return http.build();
    }
}
Output
When running the Spring Boot app, accessing any URL prompts for HTTP Basic authentication. Logging in with username 'user' and password 'password' succeeds.
⚠️

Common Pitfalls

  • Not throwing UsernameNotFoundException when user is missing causes authentication to fail silently.
  • Forgetting to encode passwords or using plain text without specifying a password encoder causes errors.
  • Not registering your UserDetailsService as a Spring bean means Spring Security won't use it.
java
/* Wrong: returns null instead of throwing exception */
@Override
public UserDetails loadUserByUsername(String username) {
    return null; // causes NullPointerException in Spring Security
}

/* Right: throws exception if user not found */
@Override
public UserDetails loadUserByUsername(String username) {
    throw new UsernameNotFoundException("User not found");
}
📊

Quick Reference

  • Implement UserDetailsService and override loadUserByUsername.
  • Return a UserDetails object with username, password, and roles.
  • Throw UsernameNotFoundException if user is not found.
  • Register your service as a Spring bean.
  • Configure Spring Security to use your UserDetailsService.

Key Takeaways

Implement UserDetailsService to load user data for Spring Security authentication.
Always throw UsernameNotFoundException if the user does not exist.
Return UserDetails with username, encoded password, and roles.
Register your UserDetailsService as a Spring bean for Spring Security to use.
Configure Spring Security to use your custom UserDetailsService in the security setup.