Keselamatan Spring dan Pengesahan JWT · Pelajaran

Pendalaman Konfigurasi HttpSecurity

Kuasai konfigurasi `HttpSecurity` untuk mentakrifkan peraturan keselamatan bagi pelbagai permintaan dan titik akhir HTTP.

Pelajaran 3 daripada 411 langkah

Pendalaman Konfigurasi HttpSecurity ialah pelajaran Keselamatan Spring dan Pengesahan JWT percuma di CoddyKit. Ini ialah pelajaran 3 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Keselamatan Spring dan Pengesahan JWT, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Keselamatan Spring dan Pengesahan JWT merangkumi sejumlah 4 pelajaran.

Apakah HttpSecurity?

HttpSecurity ialah komponen teras dalam Keselamatan Spring. Ia seperti pengawal keselamatan untuk pintu aplikasi web anda.

Ia membolehkan anda mentakrifkan peraturan untuk permintaan HTTP yang berbeza, serta mengawal pihak yang boleh mengakses bahagian tertentu aplikasi anda dan syarat yang perlu dipenuhi.

  • Pengesahan: Siapakah anda? (Adakah anda telah log masuk?)
  • Kebenaran akses: Apakah yang anda dibenarkan lakukan? (Adakah anda mempunyai keizinan?)

Rantaian Keselamatan Pertama Anda

Anda mengkonfigurasi HttpSecurity dalam bean SecurityFilterChain. Bean ini mentakrifkan rantaian penapis yang digunakan oleh Keselamatan Spring untuk melindungi aplikasi anda.

Berikut ialah persediaan minimum. Jalankannya dan cuba akses /hello. Anda akan dihalakan semula ke halaman log masuk!

Gunakan nama pengguna: user, kata laluan: password.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
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.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class SecurityApp {

    public static void main(String[] args) {
        SpringApplication.run(SecurityApp.class, args);
    }

    @GetMapping("/hello")
    public String sayHello() {
        return "Hello, secured world!";
    }
}

@Configuration
@EnableWebSecurity
class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .anyRequest().authenticated() // All requests need authentication
            )
            .formLogin(form -> form
                .permitAll() // Allow everyone to see the login page
            )
            .logout(logout -> logout
                .permitAll()); // Allow everyone to logout
        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails user = User.withDefaultPasswordEncoder()
            .username("user")
            .password("password")
            .roles("USER")
            .build();
        return new InMemoryUserDetailsManager(user);
    }
}

Menetapkan Peraturan Akses

Kaedah .authorizeHttpRequests() ialah tempat anda mula mentakrifkan peraturan kebenaran akses untuk URL aplikasi anda.

Di dalam lambda kaedah ini, anda menentukan corak dan keperluan akses untuk corak tersebut. Anggaplah ia seperti memberitahu pengawal keselamatan: "Untuk laluan ini, gunakan peraturan berikut."

Rantaian kaedah ini merupakan sebahagian daripada bean SecurityFilterChain.

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;

// This snippet shows the core authorizeHttpRequests() part.
// It assumes the surrounding Spring Boot application and 
// SecurityConfig class from the previous scene.

@Configuration
@EnableWebSecurity
class SecurityConfigSnippet {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                // Your specific rules go here!
                // Example: .requestMatchers("/public/**").permitAll()
                // Example: .anyRequest().authenticated()
            )
            .formLogin(form -> form.permitAll())
            .logout(logout -> logout.permitAll());
        return http.build();
    }
}

Laluan Awam & Terhad

Anda boleh mentakrifkan laluan yang boleh diakses oleh semua orang (permitAll()) atau langsung tiada sesiapa (denyAll()).

Gunakan requestMatchers() untuk menentukan corak URL. Ingat, peraturan diproses mengikut urutan, jadi peraturan yang lebih khusus hendaklah diletakkan dahulu.

Jalankan aplikasi ini dan cuba /public, kemudian /private (log masuk sebagai user/password), kemudian /secret.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
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.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class PublicPrivateApp {

    public static void main(String[] args) {
        SpringApplication.run(PublicPrivateApp.class, args);
    }

    @GetMapping("/public")
    public String publicContent() {
        return "This is public content!";
    }

    @GetMapping("/private")
    public String privateContent() {
        return "This is private content!";
    }

    @GetMapping("/secret")
    public String secretContent() {
        return "Top secret! No one allowed here.";
    }
}

@Configuration
@EnableWebSecurity
class SecurityConfigPublicPrivate {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/public/**").permitAll() // Anyone can access
                .requestMatchers("/secret/**").denyAll()   // No one can access
                .anyRequest().authenticated()              // All other requests need login
            )
            .formLogin(form -> form.permitAll())
            .logout(logout -> logout.permitAll());
        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails user = User.withDefaultPasswordEncoder()
            .username("user")
            .password("password")
            .roles("USER")
            .build();
        return new InMemoryUserDetailsManager(user);
    }
}

Pengguna yang Telah Log Masuk Sahaja

Kaedah .authenticated() digunakan untuk memastikan pengguna telah berjaya log masuk sebelum mengakses laluan tertentu.

Ini ialah peraturan asas untuk mana-mana bahagian aplikasi anda yang memerlukan identiti pengguna, seperti papan pemuka atau halaman profil.

// Inside your SecurityFilterChain configuration:
http
    .authorizeHttpRequests(auth -> auth
        .requestMatchers("/login", "/register").permitAll() // Public paths
        .requestMatchers("/dashboard/**").authenticated() // Needs login
        .anyRequest().denyAll() // Deny everything else by default
    )
    // ... other http configurations (formLogin, logout) ...

Mengehadkan Berdasarkan Peranan Pengguna

Anda boleh memberikan akses berdasarkan peranan pengguna menggunakan .hasRole("ROLENAME") atau .hasAuthority("ROLE_ROLENAME"). Keselamatan Spring secara automatik menambah awalan "ROLE_" pada peranan apabila menggunakan hasRole().

Ini membolehkan kawalan terperinci terhadap pihak yang boleh mengakses sumber sensitif. Jalankan aplikasi ini. Log masuk sebagai 'user' (kata laluan 'password') untuk mengakses /user-dashboard. Log masuk sebagai 'admin' (kata laluan 'admin') untuk mengakses /admin-panel.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
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.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class RoleBasedApp {

    public static void main(String[] args) {
        SpringApplication.run(RoleBasedApp.class, args);
    }

    @GetMapping("/home")
    public String home() { return "Welcome!"; }

    @GetMapping("/user-dashboard")
    public String userDashboard() { return "User Dashboard!"; }

    @GetMapping("/admin-panel")
    public String adminPanel() { return "Admin Panel!"; }
}

@Configuration
@EnableWebSecurity
class SecurityConfigRoles {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/home").permitAll()
                .requestMatchers("/user-dashboard").hasRole("USER") // Only users with ROLE_USER
                .requestMatchers("/admin-panel").hasRole("ADMIN")   // Only users with ROLE_ADMIN
                .anyRequest().authenticated() // All others need login
            )
            .formLogin(form -> form.permitAll())
            .logout(logout -> logout.permitAll());
        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails user = User.withDefaultPasswordEncoder()
            .username("user")
            .password("password")
            .roles("USER")
            .build();
        UserDetails admin = User.withDefaultPasswordEncoder()
            .username("admin")
            .password("admin")
            .roles("ADMIN")
            .build();
        return new InMemoryUserDetailsManager(user, admin);
    }
}

Urutan Peraturan Amat Penting

Apabila mentakrifkan berbilang peraturan dengan requestMatchers(), urutannya penting! Keselamatan Spring memproses peraturan dari atas ke bawah dan menggunakan peraturan pertama yang sepadan.

  • Yang Paling Khusus Dahulu: Letakkan corak URL khusus (contohnya, /api/admin/users) sebelum corak yang lebih umum (contohnya, /api/admin/**).
  • Peraturan Menyeluruh Terakhir: Pemadan .anyRequest() hampir selalu hendaklah menjadi peraturan terakhir, sebagai lalai untuk apa-apa yang tidak sepadan sebelum itu.
// Incorrect order example (the second rule is unreachable):
// auth
//   .requestMatchers("/admin/**").authenticated()
//   .requestMatchers("/admin/public").permitAll() 

// Correct order example:
// auth
//   .requestMatchers("/admin/public").permitAll()
//   .requestMatchers("/admin/**").hasRole("ADMIN")
//   .anyRequest().authenticated()

Mengkonfigurasi Log Masuk Borang

Keselamatan Spring menyediakan halaman log masuk lalai. Anda boleh menyesuaikan kelakuannya menggunakan .formLogin() dalam HttpSecurity.

Konfigurasi utama termasuk URL halaman log masuk, URL untuk memproses data log masuk, serta tempat untuk menghalakan pengguna selepas berjaya atau gagal.

// Inside your SecurityFilterChain configuration:
http
    .authorizeHttpRequests(auth -> auth
        .anyRequest().authenticated()
    )
    .formLogin(form -> form
        .loginPage("/custom-login")      // Specify custom login page URL
        .loginProcessingUrl("/authenticate") // URL to submit login data
        .defaultSuccessUrl("/dashboard", true) // Redirect after success
        .failureUrl("/custom-login?error")  // Redirect on failure
        .permitAll() // Allow access to login page and its processing
    )
    .logout(logout -> logout.permitAll());

Pemalsuan Permintaan Rentas Tapak (CSRF)

CSRF ialah serangan apabila tapak web berniat jahat memperdaya pelayar pengguna supaya membuat permintaan yang tidak dikehendaki kepada tapak dipercayai lain yang telah disahkan oleh pengguna.

Keselamatan Spring menyediakan perlindungan CSRF yang kukuh secara lalai untuk aplikasi berkeadaan.

  • Didayakan secara lalai: Untuk permintaan POST, PUT, DELETE, yang memerlukan token unik.
  • Lumpuhkan dengan berhati-hati: Gunakan .csrf().disable() hanya untuk API tanpa keadaan (contohnya, API REST yang menggunakan JWT) atau apabila anda mempunyai perlindungan CSRF yang lain.
// Inside your SecurityFilterChain configuration:
http
    // ... authorization rules ...
    .csrf(csrf -> csrf.disable()) // ONLY disable if you know what you're doing!
                                  // Common for stateless REST APIs.
    // ... formLogin, logout ...
;

Semakan Konfigurasi HttpSecurity

Anda sedang membina aplikasi Spring Boot. Anda perlu:

  • Membenarkan akses awam kepada /api/public/**.
  • Mewajibkan pengguna dengan peranan ADMIN mengakses /api/admin/**.
  • Semua permintaan lain hendaklah memerlukan mana-mana pengguna yang telah disahkan.

Konfigurasi manakah antara berikut yang mencapai keperluan ini dengan betul? (Pilih semua yang berkenaan)

Imbas Kembali Mendalam HttpSecurity

Syabas! Anda telah menguasai asas penting konfigurasi HttpSecurity.

Kita telah membincangkan:

  • Peranan HttpSecurity dalam mentakrifkan peraturan keselamatan web.
  • Penggunaan .authorizeHttpRequests() untuk kebenaran akses berasaskan laluan.
  • Kaedah seperti .permitAll(), .denyAll(), .authenticated(), dan .hasRole().
  • Kepentingan urutan peraturan apabila mentakrifkan berbilang peraturan akses.
  • Pengkonfigurasian .formLogin() untuk halaman log masuk tersuai.
  • Pemahaman dan pengurusan perlindungan CSRF.

Kemahiran ini amat penting untuk membina aplikasi Spring Boot yang kukuh dan selamat!

Percuma untuk bermula

Pelajari Java dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
12
Pelajaran
48

Soalan Lazim

Adakah pelajaran “Pendalaman Konfigurasi HttpSecurity” percuma?

Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Keselamatan Spring dan Pengesahan JWT, termasuk “Pendalaman Konfigurasi HttpSecurity”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Keselamatan Spring dan Pengesahan JWT merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Pendalaman Konfigurasi HttpSecurity”?

Kuasai konfigurasi `HttpSecurity` untuk mentakrifkan peraturan keselamatan bagi pelbagai permintaan dan titik akhir HTTP. Anda berlatih Keselamatan Spring dan Pengesahan JWT menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Keselamatan Spring dan Pengesahan JWT?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Keselamatan Spring dan Pengesahan JWT di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 3 daripada 4.

Berapa lamakah pelajaran “Pendalaman Konfigurasi HttpSecurity” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Keselamatan Spring dan Pengesahan JWT ini?

Ya. Setiap pelajaran Keselamatan Spring dan Pengesahan JWT menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Kawalan Akses Berasaskan Peranan (RBAC)
  2. Keselamatan Tahap Kaedah dengan Anotasi
  3. Pendalaman Konfigurasi HttpSecurity
  4. Melindungi Titik Akhir dengan Peraturan Akses Tersuai
← Kembali ke Keselamatan Spring dan Pengesahan JWT