Open In App

Spring Security - security none, filters none, access permitAll

Last Updated : 20 Mar, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

In Spring Boot, Spring Security is the most powerful authentication and access control framework for Java applications. Spring Security provides strong security features to protect our web applications from various security threats such as authentication, authorization, session management, and web vulnerabilities. It is highly flexible and easy to implement with Spring applications. In this article, we’ll build a simple login management system using Spring Security, focusing on public endpoints (permitAll access) and a custom authentication failure handler.

Key Terminologies:

  • Authentication: The process of verifying a user’s identity by validating their credentials (e.g., username and password).
  • Authorization: The process of determining whether an authenticated user has access to a specific resource.
  • SecurityFilterChain: A modern way to configure Spring Security rules using Java-based configuration.
  • permitAll: A method in Spring Security that allows unrestricted access to a specific endpoint or resource, regardless of the user’s authentication status.
  • Custom Authentication Failure Handler: A mechanism to handle failed authentication attempts and provide custom responses.

Project to implement Spring Security permitAll Access

We can develop the simple login management Spring application with the Custom Authentication failure handler mechanism.

Step 1: Adding Dependencies

We’ll create a Spring Boot application with the following dependencies:

  • Spring Web: For building RESTful APIs.
  • Spring Security: For authentication and authorization.
  • Spring Data MongoDB: For storing user data in MongoDB.
  • Lombok: For reducing boilerplate code.
  • Spring Dev Tools: For development convenience.

pom.xml:

XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.gfg</groupId>
    <artifactId>SecurityNone</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>SecurityNone</name>
    <description>SecurityNone</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
        <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-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Step 2: Project Structure

Once create the spring project with the above dependencies into the project the file structure looks like the below image.

Project Structure

Step 3: Configure application.properties

Add the following configuration to the application.properties file

server.port=8081

spring.data.mongodb.uri=mongodb://localhost:27017/user-Data

Step 4: Create the User Model

Create the new package named as the model and create the java class named as the User.

Go to src > com.gfg.securitynone> model > User and put the below code.

Java
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

// User class representing a user in the application
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = "users")
public class User {
    @Id
    private String id;
    private String username;
    private String password;

}

Step 5: Creat the UserRepository Interface

Create the new package named as the repository and create the java interface named as the UserRepository.

Go to src > com.gfg.securitynone> repository > UserRepository and put the below code.

UserRepository.java:

Java
package com.gfg.repository; 

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;

// Repository interface for User
@Repository
public interface UserRepository extends MongoRepository<User, String> {
    // Method to find user by username
    Optional<User> findByUsername(String username); 
}

Step 6: Create the UserService Class

Create the new package named as the service and create the java interface named as the UserService.

Go to src > com.gfg.securitynone> service > UserService and put the below code.

UserService.java:

Java
import com.example.model.User;
import com.example.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

// Service class for User
@Service
public class UserService {

    // Autowired UserRepository to interact with database
    @Autowired
    private UserRepository userRepository;

    // Method to find user by username
    public User findByUsername(String username) {
        return userRepository.findByUsername(username).orElse(null);
    }

}

Step 7: Create the SignRequest Class

Create the new package named as the request and create the java class named as the SignRequest.

Go to src > com.gfg.customauthenticationfailure > request > SigninRequest and put the below code.

SigninRequest.java:

Java
package com.gfg.request;

import lombok.Data;

@Data
public class SigninRequest {
    private String username;
    private String password;
}


Step 8: Configure Spring Security

Create the new package named as the securityconfig and create the java interface named as the SecurityConfig.

Go to src > com.gfg.customauthenticationfailure > securityconfig > SecurityConfig and put the below code.

SecurityConfig.java:

Java
package com.gfg.securityconfig;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/public/**").permitAll() 
                .requestMatchers("/api/restricted/**").authenticated()
                .anyRequest().denyAll() 
            )
            .formLogin(form -> form
                .loginProcessingUrl("/api/signin") 
                .failureHandler(authenticationFailureHandler()) 
            )
            .csrf(csrf -> csrf.disable()); 
        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public AuthenticationFailureHandler authenticationFailureHandler() {
        return new CustomAuthenticationFailureHandler();
    }
}


Step 9: Create the UserController Class

Create the java class named as the UserController.

Go to src > com.gfg.customauthenticationfailure > UserController and put the below code.

Java
package com.gfg.controller;

import com.gfg.model.User;
import com.gfg.repository.UserRepository;
import com.gfg.request.SigninRequest;
import com.gfg.service.UserService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
public class UserController {

    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;
    private final UserService userService;
    private final AuthenticationManager authenticationManager;

    public UserController(UserRepository userRepository, PasswordEncoder passwordEncoder,
                          UserService userService, AuthenticationManager authenticationManager) {
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
        this.userService = userService;
        this.authenticationManager = authenticationManager;
    }

    @GetMapping("/public")
    public String publicEndpoint() {
        return "This is a public endpoint accessible to all.";
    }

    @GetMapping("/restricted")
    public String restrictedEndpoint() {
        return "This is a restricted endpoint accessible only to authenticated users.";
    }

    @PostMapping("/signup")
    public ResponseEntity<String> signUp(@RequestBody User user) {
        try {
            user.setPassword(passwordEncoder.encode(user.getPassword()));
            userRepository.save(user);
            return ResponseEntity.status(HttpStatus.CREATED).body("User registered successfully!");
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Failed to register user: " + e.getMessage());
        }
    }

    @PostMapping("/signin")
    public ResponseEntity<String> signIn(@RequestBody SigninRequest signInRequest) {
        try {
            Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(signInRequest.getUsername(), signInRequest.getPassword())
            );
            SecurityContextHolder.getContext().setAuthentication(authentication);
            return ResponseEntity.ok("User authenticated successfully!");
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Authentication failed: " + e.getMessage());
        }
    }
}

Step 10: Run the Application

Open the main class and put the below code.

Java
package com.gfg;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// Annotation to indicate that this is a Spring Boot application
@SpringBootApplication
public class SecurityNoneApplication {

    // Main method to start the application
    public static void main(String[] args) {
        SpringApplication.run(SecurityNoneApplication.class, args);
    }

}

Step 11: Test the Application

Once completed the spring project and its run as the spring application then the application runs the port 8081.

Application RunsOutput:

GET api/public:

This endpoint is the public access point no need authentication and no filter can be apply of this endpoint.

Accessing in Browser

GET api/restricted endpoint:

Note: This endpoint need authentication to access this endpoint. We have added this api for optional to better understanding of the concept.

Authentication Needed

If we follow the above the steps, then we can successfully build the public endpoints unrestricted access and filter of the spring security project.


Next Article

Similar Reads