Open In App

Spring Security – security none, filters none, access permitAll

Last Updated : 05 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
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.

Key Terminologies

  • Authentication: This is a process of verifying the user’s identity. It collects the credentials of the users and validates them.
  • security=”none”: It is used to disable the Spring Security for specific endpoints. When security=”none” is set, it means that no Spring Security measures can be applied to specified resources, and it can effectively allow unrestricted access.
  • filters=”none”: It is similar to the security=”none”, but it specifically disables any filters configured by Spring Security for the specified endpoint or resource. Filters in Spring Security are responsible for various security-related tasks such as authentication, authorization, CSRF protection, etc. Setting filters=”none” bypasses all such security filters for the specified resource.
  • access=”permitAll”: This attribute is used to explicitly allow access to a specific endpoint or resource for all users, regardless of their authentication or authorization status. It essentially grants unauthenticated (anonymous) users’ permission to access the specified resource.

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: We can create the spring project including the below dependencies into the project.

Dependencies:

  • Spring Web
  • Spring Security
  • Spring data for MongoDB
  • Spring Dev Tools
  • Lombok

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

Project Structure

Step 2: Open the application.properties file and put the below code for the database configuration.

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

Step 3: 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 4: 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.

Java




import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
  
// Repository interface for User
@Repository
public interface UserRepository extends MongoRepository<User, String> {
    // Method to find user by username
    User findByUsername(String username);
}


Step 5: 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.

Java




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);
    }
  
}


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

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

Java




import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
  
// Data class for SigninRequest
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SigninRequest {
  
    // Username and password properties
    String username;
    String password;
}


Step 7: 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.

Java




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.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
  
// Configuration class for security settings
@Configuration
// Annotation to enable Spring Security
@EnableWebSecurity
public class SecurityConfig  {
  
    // Bean for configuring security filter chain
    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        // Configuring session management and authorization requests
        http.sessionManagement(management -> management.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authorizeRequests(
                        authorize -> authorize.requestMatchers("/api/public")
                                .permitAll().anyRequest().authenticated())
                .csrf(csrf -> csrf.disable());
        return http.build();
    }
  
    // Bean for password encoder
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}


Step 8: create the java class named as the UserController.

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

Java




import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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.*;
  
// Annotation to indicate that this class is a REST controller
@RestController
// Base mapping for all requests handled by this controller
@RequestMapping("/api")
public class UserController {
  
    // Injecting a UserRepository instance into this controller
    @Autowired
    private UserRepository userRepository;
  
    // Injecting a PasswordEncoder instance into this controller
    @Autowired
    private PasswordEncoder passwordEncoder;
  
    // Public endpoint accessible to all
    @GetMapping("/public")
    public String publicEndpoint() {
        return "This is a public endpoint accessible to all.";
    }
  
    // Restricted endpoint accessible only to authenticated users
    @GetMapping("/restricted")
    public String restrictedEndpoint() {
        return "This is a restricted endpoint accessible only to authenticated users.";
    }
  
    // Endpoint to sign up a new user
    @PostMapping("/signup")
    public ResponseEntity<String> signUp(@RequestBody User user) {
        try {
            // Encrypting the user's password before saving
            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());
        }
    }
      
    // Injecting a UserService instance into this controller
    @Autowired
    private UserService userService;
  
    // Endpoint to sign in a user
    @PostMapping("/signing")
    public ResponseEntity<String> signIn(@RequestBody SigninRequest signInRequest) {
        try {
            // Manually authenticate the user
            User user = userService.findByUsername(signInRequest.getUsername());
            if (user != null && user.getPassword().equals(signInRequest.getPassword())) {
                Authentication authentication = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword());
                SecurityContextHolder.getContext().setAuthentication(authentication);
                return ResponseEntity.ok("User authenticated successfully!");
            } else {
                // Handle invalid credentials or user not found
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid username or password");
            }
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error occurred during authentication: " + e.getMessage());
        }
    }
}


Step 9: Open the main class and put the below code.

Java




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);
    }
  
}


pom.xml

XML




<?xml version="1.0" encoding="UTF-8"?>
    <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 10: 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.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads