Spring Boot Validation & Security: Complete Guide

3 min read

Spring Boot Validation & Security: Complete Guide

1. Introduction

Input validation and authorization are two critical pillars of secure backend application development. In Spring Boot, these capabilities can be implemented cleanly using built-in annotations such as @Valid, JSR-380 validation constraints (@NotNull, @Size, @Email, etc.), and Spring Security annotations (@PreAuthorize, @Secured). This article demonstrates how these annotations work together to ensure that only valid data enters your system and that only authorized users can perform restricted operations.

2. Problem

Without proper validation and security, your application becomes vulnerable to several issues:

  • Invalid or malicious data entering the system, leading to runtime errors or data corruption.
  • Bypassing business rules such as missing required fields or improper formatting (e.g., invalid email).
  • Unauthorized access to APIs, where users without the proper roles can perform restricted actions.

A robust design must enforce validation rules at the API layer and restrict sensitive endpoints based on user roles.

3. Solution

Spring Boot solves these challenges with two powerful features:

3.1 Request Validation

  • @Valid or @Validated — triggers validation on incoming request bodies or parameters.
  • JSR-380 annotations such as:
    • @NotNull — ensures the field is not null
    • @Size — enforces length restrictions
    • @Email — enforces correct email formatting

3.2 Method-Level Security

  • @PreAuthorize — allows SpEL expressions like hasRole('ADMIN')
  • @Secured — simple role-based access control

Using these annotations together ensures data is validated before business logic executes and that sensitive operations are protected from unauthorized access.

4. Implementation

Below is a complete implementation example demonstrating validation and security features inside a Spring Boot REST API.

4.1 Add Dependencies (pom.xml)

<dependencies>
    <!-- Spring Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Validation (JSR 380) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>

    <!-- Spring Security -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
</dependencies>

4.2 Enable Method-Level Security

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;

@Configuration
@EnableMethodSecurity
public class SecurityConfig {
}

4.3 Create a DTO with Validation Rules

import javax.validation.constraints.Email;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class UserRequest {

    @NotNull(message = "Name is required")
    @Size(min = 2, max = 50, message = "Name must be between 2 and 50 characters")
    private String name;

    @NotNull(message = "Email is required")
    @Email(message = "Email format is invalid")
    private String email;

    @NotNull(message = "Password is required")
    @Size(min = 8, message = "Password must be at least 8 characters long")
    private String password;

    // getters and setters
}

4.4 Create a Secured Service Layer

import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @PreAuthorize("hasRole('ADMIN')")
    public String createUser(UserRequest request) {
        return "User created: " + request.getEmail();
    }

    @Secured("ROLE_USER")
    public String getUserProfile(String email) {
        return "Profile for: " + email;
    }
}

4.5 Create the Controller with @Valid

import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;

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

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @PostMapping
    public String createUser(@Valid @RequestBody UserRequest request) {
        return userService.createUser(request);
    }

    @GetMapping("/{email}")
    public String getProfile(@PathVariable("email") String email) {
        return userService.getUserProfile(email);
    }
}

4.6 Example Validation Error Response

{
  "timestamp": "2025-11-24T20:00:00",
  "status": 400,
  "errors": [
    "Name must be between 2 and 50 characters",
    "Email format is invalid",
    "Password must be at least 8 characters long"
  ]
}

4.7 Example Security Behavior

  • A user without ADMIN role calling POST /api/users → HTTP 403 Forbidden
  • A user with USER role calling GET /api/users/{email} → Success
  • A user with no roles calling either endpoint → HTTP 403 Forbidden

5. Conclusion

Validation and security are essential components of a well-designed Spring Boot application. Using annotations such as @Valid, @NotNull, @Email, @PreAuthorize, and @Secured, developers can easily enforce strict data integrity and apply precise access control policies. This approach reduces boilerplate code, increases maintainability, and protects your application from invalid input and unauthorized access.

🤞 Never miss a story from us, get weekly updates to your inbox!

Leave a Reply

Your email address will not be published. Required fields are marked *