# Securing APIs with Spring Security & JWT

## **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.

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

#### **2️⃣ Payload (Claims)**

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

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

#### **3️⃣ Signature**

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

```python
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`:

```python
<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**

```python
@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**

```python
@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**

```python
@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**

```python
@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**](https://www.bits8byte.com/) **for more hands-on tutorials!** 🚀 If you found this helpful, share it with others! 🔥

---
