Skip to main content

Command Palette

Search for a command to run...

Securing APIs with Spring Security & JWT

Published
3 min readView as Markdown
Securing APIs with Spring Security & JWT
I
Welcome to Bits8Byte! I’m Ish, an AI Engineer with 11+ years of experience across software engineering, automation, cloud, and AI-driven systems. This blog is where I share practical insights, technical deep dives, and real-world lessons from building modern software and exploring the fast-moving world of AI. My background spans Java, Spring Boot, Python, FastAPI, AWS, Docker, Kubernetes, DevOps, observability, and automation. Today, my work is increasingly focused on AI engineering, including LLM applications, AI agents, production-grade microservices, and scalable cloud-native architectures. Here, you’ll find thoughtful writing on AI trends, engineering best practices, software architecture, and the mindset required to adapt and grow in the age of AI. My aim is not just to explain technology, but to make it useful, practical, and grounded in real implementation experience. Thanks for stopping by. I hope this space helps you learn something valuable, think more deeply, and stay ahead in a rapidly evolving industry.

1️⃣ Introduction

With the rise of RESTful APIs, security has become a critical concern. Traditional session-based authentication doesn’t work well for stateless architectures, leading to the adoption of JSON Web Tokens (JWT) for securing APIs.

In this blog, we’ll explore why JWT is widely used, its working mechanism, and how to integrate JWT authentication with Spring Security in a Spring Boot application. By the end, you’ll have a fully functional token-based authentication system! 🚀


2️⃣ Why Use JWT for API Security?

🔹 What is JWT?

JWT (JSON Web Token) is a compact, URL-safe token format that allows the secure transmission of claims between parties.

🔹 Why JWT Over Traditional Authentication?

Stateless & Scalable – No need for server-side session storage. ✅ Efficient & Lightweight – Encodes user data directly into the token. ✅ Secure – Uses cryptographic signatures to verify authenticity.

📌 JWT (JSON Web Token): A self-contained, compact token format for securely transmitting data between parties.


3️⃣ How JWT Works (Structure, Claims, Signature)

JWT consists of three parts, separated by dots (.):

🔹 JWT Structure

HEADER.PAYLOAD.SIGNATURE

1️⃣ Header

Contains metadata about the algorithm used to sign the token.

{
  "alg": "HS256",
  "typ": "JWT"
}

2️⃣ Payload (Claims)

Stores user-related data (e.g., username, roles, expiration time).

{
  "sub": "john_doe",
  "role": "USER",
  "exp": 1712345678
}

3️⃣ Signature

A cryptographic hash used to validate the token’s authenticity.

HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

📌 Bearer Token: A type of access token sent in the Authorization header when making API requests.

📌 Token Expiry: JWTs include an exp (expiration) claim to determine validity.


4️⃣ Spring Security Integration with JWT

Spring Security doesn’t support JWT out of the box, but we can integrate JWT authentication manually by implementing:

  • Custom Authentication Filter to intercept login requests.

  • JWT Token Provider for generating and validating tokens.

  • Spring Security Configuration to apply token-based authentication.


5️⃣ Configuring Token-Based Authentication

🔹 Step 1: Add Dependencies

Add the following dependencies to pom.xml:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.11.2</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

🔹 Step 2: Create JWT Utility Class

@Component
public class JwtUtil {
    private final String SECRET_KEY = "mySecretKey";

    public String generateToken(String username) {
        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + 86400000))
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
    }

    public String extractUsername(String token) {
        return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getSubject();
    }
}

🔹 Step 3: Create JWT Authentication Filter

@Component
public class JwtRequestFilter extends OncePerRequestFilter {
    @Autowired
    private JwtUtil jwtUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        final String authorizationHeader = request.getHeader("Authorization");

        if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
            String token = authorizationHeader.substring(7);
            String username = jwtUtil.extractUsername(token);
            SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>()));
        }

        filterChain.doFilter(request, response);
    }
}

🔹 Step 4: Configure Spring Security to Use JWT

@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/auth/**").permitAll()
                .anyRequest().authenticated()
            )
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
        return http.build();
    }
}

📌 Refresh Tokens: A mechanism to request new access tokens when the current token expires, without requiring re-authentication.


6️⃣ Hands-on: Implementing JWT Authentication in a Spring Boot API

🔹 Step 1: Create an Authentication Controller

@RestController
@RequestMapping("/auth")
public class AuthController {
    @Autowired
    private JwtUtil jwtUtil;

    @PostMapping("/login")
    public ResponseEntity<String> login(@RequestBody AuthRequest request) {
        String token = jwtUtil.generateToken(request.getUsername());
        return ResponseEntity.ok(token);
    }
}

🔹 Step 2: Test Authentication Flow

  1. Login Request: Send a POST /auth/login request with a valid username.

  2. Receive JWT Token: Store the received token.

  3. Send Authenticated Request: Use the token in the Authorization header (Bearer token).


7️⃣ Call to Action

Want to learn more about Spring Security? Follow me on Bits8Byte for more hands-on tutorials! 🚀 If you found this helpful, share it with others! 🔥


Spring Security

Part 4 of 4

A comprehensive guide to understanding and implementing security in Spring Boot applications using the latest version of Spring Security. Covering authentication, authorization, JWT, OAuth2, and advanced security concepts.

Start from the beginning

Understanding Spring Security: Why It Matters

1️⃣ Introduction In today's digital world, securing applications is more important than ever. With increasing cyber threats, protecting sensitive data and ensuring that only authorized users access certain parts of an application is critical. This is...