How do you create a custom user details service in Spring Security?

Table of Contents

Introduction

In Spring Security, **UserDetailsService** is an interface that defines how user information is retrieved for authentication. By default, Spring Security provides a basic in-memory or database-backed implementation of UserDetailsService. However, in many cases, you may need to create your own custom UserDetailsService to handle user authentication and authorization with your specific requirements.

A custom **UserDetailsService** allows you to retrieve user details (such as username, password, roles, and other attributes) from your own database or another external source. This guide will walk you through creating a custom UserDetailsService in Spring Security to authenticate users from a custom source (e.g., a database or an external API).

What is UserDetailsService?

The UserDetailsService is responsible for fetching user-specific data, such as:

  • Username
  • Password
  • Authorities (roles and permissions)
  • Any other necessary attributes that define the user

Spring Security uses this information to authenticate users and make authorization decisions.

The UserDetailsService Interface

This interface has only one method:

  • **loadUserByUsername(String username)**: This method is responsible for fetching user data based on the username. It returns a UserDetails object that holds the user's information.

Step-by-Step Implementation of Custom UserDetailsService

Let’s create a custom UserDetailsService that retrieves user details from a database.

Step 1: Set Up Spring Boot and Dependencies

Add the necessary dependencies to your pom.xml (for Maven) or build.gradle (for Gradle).

For Maven (pom.xml):

For Gradle (build.gradle):

Step 2: Create the User Entity

We will assume you are using Spring Data JPA to manage your user data in a relational database. First, create a User entity class that represents the user in your database.

Step 3: Create the UserRepository

Next, create a repository interface to access the User entity data from the database.

Step 4: Implement the Custom UserDetailsService

Now, implement the UserDetailsService interface. This implementation will query the database to load the user by their username and return a UserDetails object.

In this implementation:

  • The loadUserByUsername() method fetches the user from the database using the UserRepository.
  • If the user is found, we map the User entity to a Spring Security User object.
  • The roles are converted to **GrantedAuthority** objects using SimpleGrantedAuthority.

Step 5: Configure Spring Security to Use the Custom UserDetailsService

Now, configure Spring Security to use your custom UserDetailsService for authentication. You can do this by creating a configuration class that extends WebSecurityConfigurerAdapter.

Step 6: Test the Custom UserDetailsService

With this configuration, when a user logs in, Spring Security will use your CustomUserDetailsService to retrieve their details from the database and authenticate them.

  • Ensure your database has the necessary users and roles.
  • You can create a test login endpoint (/login) to verify the user authentication.

Conclusion

Creating a custom UserDetailsService in Spring Security allows you to control how user information is fetched and used for authentication. This is particularly useful when the user data is stored in an external source like a database, and you need more control over how users are authenticated and authorized.

In this guide, we implemented a custom UserDetailsService to authenticate users from a database, which is a common use case for enterprise applications.

Similar Questions