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

Tosca Licensing: Types and Considerations

Using Hibernate ORM for Fullstack Java Data Management