0Pricing
Spring Security 6 & JWT Authentication · Pelajaran

Menerapkan Penyaring JWT Kustom

Bangun `OncePerRequestFilter` kustom untuk mencegat permintaan, mengekstrak JWT, dan mengautentikasi pengguna.

Menerapkan Penyaring JWT Kustom adalah pelajaran Spring Security 6 & JWT Authentication gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Spring Security 6 & JWT Authentication, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Spring Security 6 & JWT Authentication mencakup 4 pelajaran total.

Bagian dari pelajaran ini belum diterjemahkan dan ditampilkan dalam bahasa Inggris.

Why a Custom JWT Filter?

When using JSON Web Tokens (JWTs) for authentication, Spring Security doesn't inherently know how to process them. This is where a custom filter comes in!

A custom JWT filter intercepts incoming requests to:

  • Extract the JWT.
  • Validate its authenticity and expiration.
  • Inform Spring Security about the authenticated user.

The OncePerRequestFilter Base

For our custom JWT filter, we'll extend Spring's OncePerRequestFilter. This base class guarantees that your filter logic runs exactly once per HTTP request, preventing redundant processing.

  • It simplifies filter implementation.
  • Ensures efficiency for each request.
  • It's ideal for authentication logic.

Basic Filter Structure

Every custom filter extending OncePerRequestFilter must override the doFilterInternal method. This is where our JWT processing logic will reside.

It provides access to the HttpServletRequest, HttpServletResponse, and the FilterChain to pass the request along.

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;

public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(
        HttpServletRequest request,
        HttpServletResponse response,
        FilterChain filterChain
    ) throws ServletException, IOException {
        // Our JWT logic will go here
        filterChain.doFilter(request, response);
    }
}

Extracting the JWT

The first step in our filter is to extract the JWT from the incoming request. JWTs are typically sent in the Authorization header, prefixed with Bearer .

We need to check for this header and remove the 'Bearer ' part to get the raw token.

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;

public class JwtAuthenticationFilter extends OncePerRequestFilter {

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

        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            jwt = authHeader.substring(7); // Remove "Bearer " prefix
            System.out.println("Extracted JWT: " + jwt.substring(0, 5) + "...");
        } else {
            System.out.println("No JWT found or invalid header.");
        }

        filterChain.doFilter(request, response);
    }
}

Validating & Parsing (Concept)

After extraction, the JWT must be validated. This involves:

  • Signature verification: Ensuring the token hasn't been tampered with.
  • Expiration check: Confirming the token is still valid.
  • Claim extraction: Retrieving information like the username (subject) from the token's payload.

This validation is typically handled by a dedicated JwtService or similar utility, which our filter would use.

Loading User Details (Concept)

Once the JWT is validated and the username (or user ID) is extracted, the filter needs to load the user's specific details. This is usually done using Spring Security's UserDetailsService.

The UserDetailsService fetches the UserDetails object, which contains information like roles and authorities needed for authorization.

Setting Authentication Context

The final crucial step is to inform Spring Security that the user is authenticated for the current request. This is done by creating an Authentication object (e.g., UsernamePasswordAuthenticationToken) and setting it in the SecurityContextHolder.

Once set, Spring Security will recognize the user as authenticated for the duration of the request.

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        // Simulate a UserDetails object loaded from DB
        UserDetails userDetails = new User(
            "exampleUser", "[PASSWORD_HASH]", new ArrayList<>()
        );

        // Create an Authentication token
        UsernamePasswordAuthenticationToken authToken =
            new UsernamePasswordAuthenticationToken(
                userDetails, null, userDetails.getAuthorities()
            );

        // Set the Authentication in the SecurityContextHolder
        SecurityContextHolder.getContext().setAuthentication(authToken);

        System.out.println("Authentication set for: " +
            SecurityContextHolder.getContext().getAuthentication().getName());

        // Clear context after request (or for next test)
        SecurityContextHolder.clearContext();
    }
}

Runnable Filter Logic Example

Let's see a simplified, runnable example that mimics the core logic of our custom JWT filter. It simulates extracting a token and setting authentication based on its presence.

This example uses mock components to show the flow without a full Spring Boot setup.

import java.util.HashMap;
import java.util.Map;

// Simulate Spring Security components needed for the filter logic
class MockSecurityContextHolder {
    private static String authenticatedUser = null;

    public static String getAuthentication() {
        return authenticatedUser;
    }

    public static void setAuthentication(String user) {
        authenticatedUser = user;
    }

    public static void clearContext() {
        authenticatedUser = null;
    }
}

public class Main {

    // This method simulates the core logic of doFilterInternal
    public static void simulateJwtFilter(Map<String, String> requestHeaders) {
        System.out.println("--- Simulating JWT Filter Logic ---");

        final String authHeader = requestHeaders.get("Authorization");
        String jwt = null;
        String username = null;

        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            jwt = authHeader.substring(7);
            // In a real app, this extracts username from JWT payload
            username = "coddyuser"; // Simplified: assume "coddyuser" from a valid JWT
            System.out.println("Filter: JWT found: " + jwt.substring(0, 5) + "...");
        } else {
            System.out.println("Filter: No JWT found or invalid header format.");
        }

        // Check if user is already authenticated
        if (username != null && MockSecurityContextHolder.getAuthentication() == null) {
            // Simulate JWT validation (signature, expiration, etc.)
            boolean tokenValid = true; // Assume valid for this simple demo

            if (tokenValid) {
                // In a real filter, we'd load UserDetails and create an Authentication object
                MockSecurityContextHolder.setAuthentication(username);
                System.out.println("Filter: User '" + username + "' authenticated and context set.");
            } else {
                System.out.println("Filter: JWT validation failed.");
            }
        } else if (username != null && MockSecurityContextHolder.getAuthentication() != null) {
            System.out.println("Filter: User '" + username + "' already authenticated for this request.");
        }

        // In a real filter, this would call filterChain.doFilter(...)
        System.out.println("Filter: Request passed to next filter/handler.");
        System.out.println("--- Filter Logic End ---");
    }

    public static void main(String[] args) {
        // Scenario 1: Request with a valid JWT
        Map<String, String> headers1 = new HashMap<>();
        headers1.put("Authorization", "Bearer abc.def.ghi");
        simulateJwtFilter(headers1);
        System.out.println("Main: SecurityContext has authentication: " +
            (MockSecurityContextHolder.getAuthentication() != null ? MockSecurityContextHolder.getAuthentication() : "None"));
        MockSecurityContextHolder.clearContext(); // Clean up

        System.out.println("\n");

        // Scenario 2: Request without a JWT
        Map<String, String> headers2 = new HashMap<>();
        simulateJwtFilter(headers2);
        System.out.println("Main: SecurityContext has authentication: " +
            (MockSecurityContextHolder.getAuthentication() != null ? MockSecurityContextHolder.getAuthentication() : "None"));
        MockSecurityContextHolder.clearContext(); // Clean up
    }
}

Integrating with Spring Security

After creating our JwtAuthenticationFilter, we need to register it with Spring Security's filter chain. This is typically done in your security configuration class (e.g., SecurityConfig) using HttpSecurity.

We use .addFilterBefore() to ensure our JWT filter runs before Spring Security's default authentication filters, like UsernamePasswordAuthenticationFilter.

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.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

// Assuming JwtAuthenticationFilter is defined elsewhere
class JwtAuthenticationFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response, jakarta.servlet.FilterChain filterChain) throws jakarta.servlet.ServletException, java.io.IOException {
        // Simplified for config demo
        filterChain.doFilter(request, response);
    }
}

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    private final JwtAuthenticationFilter jwtAuthFilter;

    // Inject our custom JWT filter
    public SecurityConfig(JwtAuthenticationFilter jwtAuthFilter) {
        this.jwtAuthFilter = jwtAuthFilter;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf(csrf -> csrf.disable()) // Disable CSRF for stateless APIs
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/auth/**").permitAll() // Public endpoints
                .anyRequest().authenticated() // Secure all other requests
            )
            // Add our custom JWT filter BEFORE the default UsernamePasswordAuthenticationFilter
            .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }
}

Filter Chain Challenge

Consider the JwtAuthenticationFilter we've discussed. What are its key responsibilities in the Spring Security filter chain when handling JWT-based authentication?

Lesson Recap: Custom JWT Filter

In this lesson, we explored how to build a custom OncePerRequestFilter to handle JWT authentication in Spring Security.

  • We learned to extract JWTs from the Authorization header.
  • We understood the conceptual steps of validating the token and loading user details.
  • We saw how to authenticate the user by setting the SecurityContextHolder.
  • Finally, we covered how to integrate this filter into Spring Security's filter chain using HttpSecurity.addFilterBefore().

This custom filter is crucial for integrating JWTs seamlessly into your secure Spring Boot applications.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Menerapkan Penyaring JWT Kustom” gratis?

Ya — teks lengkap “Menerapkan Penyaring JWT Kustom” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Spring Security 6 & JWT Authentication, upgrade ke CoddyKit PRO. Kursus Spring Security 6 & JWT Authentication mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Menerapkan Penyaring JWT Kustom”?

Bangun `OncePerRequestFilter` kustom untuk mencegat permintaan, mengekstrak JWT, dan mengautentikasi pengguna. Kamu berlatih Spring Security 6 & JWT Authentication dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Spring Security 6 & JWT Authentication?

Tidak diperlukan pengalaman sebelumnya. Spring Security 6 & JWT Authentication di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.

Berapa lama pelajaran “Menerapkan Penyaring JWT Kustom” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Spring Security 6 & JWT Authentication ini?

Ya. Setiap pelajaran Spring Security 6 & JWT Authentication menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Merancang Alur Autentikasi JWT
  2. Menerapkan Penyaring JWT Kustom
  3. Integrasi AuthenticationManager dan Penyedia
  4. Menangani Kesalahan Autentikasi dan Titik Masuk
← Kembali ke Spring Security 6 & JWT Authentication