Spring Security - Understanding UserDetailsService and creating a custom one

[Updated: Sep 1, 2017, Created: Aug 31, 2017]

UserDetailsService is used to load user-specific data. In previous examples, we have been using either in-memory authentication which uses InMemoryUserDetailsManager or JDBC authentication which uses JdbcUserDetailsManager. Both of which are implementations of UserDetailsService.

The UserDetailsService interface

package org.springframework.security.core.userdetails;
public interface UserDetailsService {
	UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;

The method loadUserByUsername() locates the user by the username. Spring internally uses the returned non-null UserDetails object to verify the password and roles against the client's entered values.

AuthenticationProvider vs UserDetailsService

UserDetailsService is not an alternative to AuthenticationProvider but it is used for a different purpose i.e. to load user details. Typically, an AuthenticationProvider implementation can use UserDetailsService instance to retrieve user details during its authentication process. For example, DaoAuthenticationProvider, in case of JDBC-authentication, uses JdbcUserDetailsManager as an implementation of UserDetailsService. In case of in-memory authentication, DaoAuthenticationProvider uses InMemoryUserDetailsManager implementation.


This example will demonstrate how to create and register a custom UserDetailsService.

Implementing UserDetailsService

public class MyUserDetailsService implements UserDetailsService {
    private static List<UserObject> users = new ArrayList();

    public MyUserDetailsService() {
        //in a real application, instead of using local data,
        // we will find user details by some other means e.g. from an external system
        users.add(new UserObject("erin", "123", "ADMIN"));
        users.add(new UserObject("mike", "234", "ADMIN"));

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Optional<UserObject> user = users.stream()
                                         .filter(u -> u.name.equals(username))
        if (!user.isPresent()) {
            throw new UsernameNotFoundException("User not found by name: " + username);
        return toUserDetails(user.get());

    private UserDetails toUserDetails(UserObject userObject) {
        return User.withUsername(userObject.name)

    private static class UserObject {
        private String name;
        private String password;
        private String role;

        public UserObject(String name, String password, String role) {
            this.name = name;
            this.password = password;
            this.role = role;

Java Config class

public class AppConfig extends WebSecurityConfigurerAdapter {

  protected void configure(HttpSecurity http) throws Exception {

  public void configure(AuthenticationManagerBuilder builder)
          throws Exception {
      builder.userDetailsService(new MyUserDetailsService());

  public ViewResolver viewResolver() {
      InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
      return viewResolver;

We can also register our UserDetailsService as a bean by using @Bean or @Component, as an alternative to above AuthenticationManagerBuilder configuration.

Also note that with above configuration, DaoAuthenticationProvider is used as an AuthenticationProvider.

The Controller

public class MyController {

  public String handleRequest(HttpServletRequest request, Model model) {
      Authentication auth = SecurityContextHolder.getContext()
      model.addAttribute("uri", request.getRequestURI())
           .addAttribute("user", auth.getName())
           .addAttribute("roles", auth.getAuthorities());
      return "my-page";

The JSP page


<html lang="en">
 <p>URI: ${uri} <br/>
 User :  ${user} <br/>
 roles:  ${roles} <br/><br/>
 <form action="/logout" method="post">
     <input type="hidden"
  <input type="submit" value="Logout">

To try examples, run embedded tomcat (configured in pom.xml of example project below):

mvn tomcat7:run-war


Entering the credential:

Logging out:

Entering wrong credentials:

Example Project

Dependencies and Technologies Used :

  • spring-security-web 4.2.3.RELEASE: spring-security-web.
  • spring-security-config 4.2.3.RELEASE: spring-security-config.
  • spring-webmvc 4.3.9.RELEASE: Spring Web MVC.
  • javax.servlet-api 3.1.0 Java Servlet API
  • JDK 1.8
  • Maven 3.3.9

Custom UserDetailsService Example Select All Download
  • user-details-service-example
    • src
      • main
        • java
          • com
            • logicbig
              • example
        • webapp
          • WEB-INF
            • views

See Also