Fullstack Java: Setting Up Spring Security for Custom Authentication

When building fullstack Java applications, securing user authentication is one of the most critical steps. While Spring Security provides robust and ready-to-use security features out of the box, real-world applications often require custom authentication to meet specific business requirements. This could include authenticating users from a database, using JWT tokens, or integrating third-party identity providers.

In this blog, we’ll walk through how to set up Spring Security for custom authentication in a fullstack Java application using Spring Boot on the backend and a frontend framework like React or Angular.


Why Custom Authentication?

Default configurations in Spring Security offer basic form-based login and HTTP Basic authentication. However, real applications usually need:

Authentication from a custom user database

Role-based access control

Custom login endpoints (e.g., /api/auth/login)

JWT or token-based stateless authentication

Custom authentication allows you to integrate these features and design a system tailored to your needs.


Step 1: Add Spring Security to Your Project

Start with a Spring Boot project and include the necessary dependencies in your pom.xml:

xml


<dependency>

  <groupId>org.springframework.boot</groupId>

  <artifactId>spring-boot-starter-security</artifactId>

</dependency>

<dependency>

  <groupId>org.springframework.boot</groupId>

  <artifactId>spring-boot-starter-web</artifactId>

</dependency>

<dependency>

  <groupId>org.springframework.boot</groupId>

  <artifactId>spring-boot-starter-data-jpa</artifactId>

</dependency>


Step 2: Create a Custom User Entity and Repository

Define your User entity and repository to fetch users from the database:


java


@Entity

public class User {

    @Id

    private String username;

    private String password;

    private String role;

}

java


public interface UserRepository extends JpaRepository<User, String> {

    Optional<User> findByUsername(String username);

}


Step 3: Implement a Custom UserDetailsService

Spring Security uses UserDetailsService to load user-specific data:

java


@Service

public class CustomUserDetailsService implements UserDetailsService {

    @Autowired

    private UserRepository userRepository;


    @Override

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        User user = userRepository.findByUsername(username)

            .orElseThrow(() -> new UsernameNotFoundException("User not found"));

        

        return new org.springframework.security.core.userdetails.User(

            user.getUsername(), user.getPassword(),

            Collections.singleton(new SimpleGrantedAuthority("ROLE_" + user.getRole()))

        );

    }

}


Step 4: Configure Security Filter Chain

You can now set up a security configuration class using the newer Spring Security style:

java


@Configuration

@EnableWebSecurity

public class SecurityConfig {


    @Autowired

    private CustomUserDetailsService userDetailsService;


    @Bean

    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

        http.csrf().disable()

            .authorizeHttpRequests()

            .requestMatchers("/api/auth/**").permitAll()

            .anyRequest().authenticated()

            .and()

            .userDetailsService(userDetailsService)

            .formLogin().loginProcessingUrl("/api/auth/login")

            .successHandler((req, res, auth) -> res.setStatus(HttpServletResponse.SC_OK))

            .failureHandler((req, res, ex) -> res.sendError(HttpServletResponse.SC_UNAUTHORIZED));


        return http.build();

    }


    @Bean

    public PasswordEncoder passwordEncoder() {

        return new BCryptPasswordEncoder();

    }

}


Step 5: Create Custom Login Controller (Optional)

For token-based authentication or advanced control, you might replace the default login mechanism with a REST endpoint:


java


@RestController

@RequestMapping("/api/auth")

public class AuthController {


    @PostMapping("/login")

    public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {

        // Authenticate and return JWT/token

        return ResponseEntity.ok("Authenticated!");

    }

}


Final Thoughts

Custom authentication in Spring Security gives you full control over how users are authenticated and authorized in your Java application. With a clean architecture and integration of UserDetailsService, role-based access, and REST-friendly login endpoints, you can seamlessly protect your backend while enabling secure communication with your frontend. 

Learn FullStack Java Course in Hyderabad

Read More : Fullstack Java: Using AWS S3 for File Storage in Java Applications

Read More : Fullstack Java: How to Handle Large Scale Data in Spring Boot

Read More : Fullstack Java: How to Build a Blog Application with Spring Boot and Thymeleaf

Visit Our IHUB Talent Institute Hyderabad
Get Direction

Comments

Popular posts from this blog

How to Use Tosca's Test Configuration Parameters

Using Playwright with Electron-Based Applications

Top 5 UX Portfolios You Should Learn From