User Provisioning Filter

In this lesson, we'll implement a filter that creates new users in our database when they first log in, ensuring every authenticated user has a corresponding User in the database.

Understanding User Provisioning

A user provisioning filter intercepts incoming requests after authentication to check if a user exists in our database and creates them if they don't.

This filter is valuable because it automatically creates user records in our database when users first authenticate through Keycloak, without requiring additional API endpoints or manual intervention.

Implementing the User Repository

First, we need a repository to interact with our user database:

@Repository public interface UserRepository extends JpaRepository<User, UUID> { }

By extending JpaRepository, we get built-in methods for:

  • Creating users
  • Checking if users exist
  • Finding users by ID
  • And many other common database operations

Creating the User Provisioning Filter

The filter needs to:

  1. Extract user information from the JWT token
  2. Check if the user exists in our database
  3. Create the user if they don't exist

Here's the implementation:

@Component @RequiredArgsConstructor public class UserProvisioningFilter extends OncePerRequestFilter { private final UserRepository userRepository; @Override protected void doFilterInternal( HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // Get the authentication object from the security context Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication != null && authentication.isAuthenticated() && authentication.getPrincipal() instanceof Jwt jwt) { // Extract the user ID from the JWT subject UUID keycloakId = UUID.fromString(jwt.getSubject()); if (!userRepository.existsById(keycloakId)) { User user = new User(); user.setId(keycloakId); user.setName(jwt.getClaimAsString("preferred_username")); user.setEmail(jwt.getClaimAsString("email")); userRepository.save(user); } } filterChain.doFilter(request, response); } }

The filter extends OncePerRequestFilter to ensure it only runs once per request.

We use @RequiredArgsConstructor to inject our UserRepository through constructor injection.

The filter checks if we have an authenticated user with a JWT token, then extracts the user ID and creates a new user record if one doesn't exist.

Summary

  • Created the UserRepository interface
  • Implemented the UserProvisioningFilter
© 2026 Devtiro Ltd. All rights reserved