ข้าม​ไป​ยัง​เนื้อหา

chain ที่​วาง​ผิด​ลำดับ แล้ว​แอป​ไม่​ยอม​ส​ตาร์ต

สาม​บท​ที่​ผ่าน​มา​มี SecurityFilterChainSecurityFilterChainรายการ filter ที่​คำขอ​ต้อง​เดิน​ผ่าน​ก่อน​ถึง `DispatcherServlet` · ประกาศ​เป็น bean · มี​ได้​หลาย​ตัว และ​ตัว​ที่ matcher ตรง​เป็น​ตัว​แรก​คือ​ตัว​ที่​ทำงาน ตัว​เดียว กฎ​ทุก​ข้อ​จึง​อยู่​ใน​ที่​เดียวกัน · ระบบ​จริง​มัก​ไม่​เป็น​แบบ​นั้น · API กับ​หน้า​เว็บ​มัก​ต้องการ​กฎ​คนละ​ชุด

บท​นี้​ประกาศ​สอง​ตัว แล้ว​วัด​ว่า​เกิด​อะไร​ขึ้น

ตัว​ที่​ไม่​ประกาศ​ขอบเขต ครอบ​ทุก​คำขอ​โดย​ปริยาย

chain กว้าง · ไม่มี securityMatcher
@Bean
@Order(1)
fun wide(http: HttpSecurity): SecurityFilterChain {
http.authorizeHttpRequests { it.anyRequest().hasRole("ADMIN") }
http.httpBasic { }
return http.build()
}
chain แคบ · ประกาศ​ขอบเขต​ไว้​ที่​ปลาย​ทาง​เดียว
@Bean
@Order(2)
fun narrow(http: HttpSecurity): SecurityFilterChain {
http.securityMatcher("/open")
http.authorizeHttpRequests { it.anyRequest().permitAll() }
return http.build()
}

securityMatchersecurityMatcherการ​กำหนด​ว่า `SecurityFilterChain` ตัว​หนึ่ง​ครอบ​คำขอ​แบบ​ไหน · chain ที่​ไม่มี matcher ครอบ​ทุก​คำขอ · จึง​กลืน chain ที่​อยู่​ถัด​ไป​ทั้งหมด​ถ้า​ประกาศ​ไว้​ก่อน คือ​สิ่ง​ที่​บอก​ว่า chain ตัว​หนึ่ง​ครอบ​คำขอ​แบบ​ไหน · ตัว​ที่​ไม่​ประกาศ ครอบ​ทุก​อย่าง

@Order ของ chainchain orderลำดับ​ที่ `FilterChainProxy` ไล่​หา chain ที่​ตรง​กับ​คำขอ · มัน​หยุด​ที่​ตัว​แรก​ที่​ตรง แล้ว​ไม่​ปรึกษา​ตัว​ที่​เหลือ · กฎ​ใน​ตัว​ที่​ถูก​กลืน​จึง​ไม่มี​ผล ทั้ง​ที่ code อ่าน​ดู​เหมือน​มี คือ​ลำดับ​ที่​ระบบ​ไล่​หา​ตัว​ที่​ตรง · เลข​น้อย​มา​ก่อน

ผม​คาด​ว่า​กฎ​จะ​เงียบ​หาย แต่​แอป​สร้าง bean ไม่​สำเร็จ​เลย

หัวข้อ​ที่​มีชื่อ​ว่า “ผม​คาด​ว่า​กฎ​จะ​เงียบ​หาย แต่​แอป​สร้าง bean ไม่​สำเร็จ​เลย”

ผม​เดา​ผิด และ​การ​เดา​ผิด​นี้​เป็น​เนื้อหา​ของ​บท

ตอน​วางแผน​คอร์ส ผม​เขียน​ไว้​ว่า​คำขอ​ไป​ที่ /open จะ​ถูก chain กว้าง​รับ​ไป​ก่อน แล้ว​ได้ 401 ส่วน​กฎ permitAll ใน​ตัว​แคบ​จะ​ไม่มี​ใคร​ได้​ใช้ · เงียบๆ แบบ​นั้น

การ​วัด​ตอบ​ว่า แอป​สร้าง bean ไม่​สำเร็จ​เลย

org.springframework.security.web.UnreachableFilterChainException

ไม่มี​คำขอ​ไหน​ถูก​ยิง​เลย เพราะ​ไม่มี​เซิร์ฟเวอร์​ให้​ยิง

ความ​ผิด​พลาด​ที่​ย้าย​จาก​เงียบ​มา​เป็น​ดัง

ใน​รุ่น​ก่อน​หน้า การ​วาง​ลำดับ​แบบ​นี้​เป็น​ความ​ผิด​พลาด​ที่​ทำงาน​ได้ · แอป​ขึ้น คำขอ​วิ่ง และ​กฎ​ที่​คุณ​เขียน​ไว้​อย่าง​ตั้งใจ​ก็​ไม่​เคย​ถูก​ใช้

ตอน​นี้​มัน​เป็น​ความ​ผิด​พลาด​ที่​หยุด​คุณ​ตั้งแต่​ต้น · นี่​คือ​การ​เปลี่ยนแปลง​ที่​ดี ต่อ​ให้​มัน​ทำให้​คุณ​เสีย​เวลา​ตอน​อัป​เกรด

เปลี่ยน​แค่​สอง​เลข ไม่​แตะ​อย่าง​อื่น

ให้​ตัว​แคบ​เป็น @Order(1) และ​ตัว​กว้าง​เป็น @Order(2) · แอป​ส​ตาร์ต​ได้

ทรงGET /openchain ที่​รับ
กว้าง​ก่อนแอป​ส​ตาร์ต​ไม่​ขึ้น—
แคบ​ก่อน200narrow

รหัส 200 อย่าง​เดียว​พิสูจน์​ไม่​ได้​ว่า chain ไหน​เป็น​คน​รับ เพราะ​ทั้ง​สอง​ตัว อาจ​ให้ 200 ได้​ด้วย​เหตุผล​คนละ​อย่าง · ป้าย​ใน​ช่อง​ขวา​จึง​มา​จาก filter ที่​เรา​แทรก เข้าไป​ใน​แต่ละ chain เพื่อ​เขียน header บอก​ชื่อ​ตัว​เอง

เรียง​จาก​แคบ​ไป​กว้าง และ​ให้​ตัว​ที่​ครอบ​ทุก​อย่าง​อยู่​ท้าย​สุด​เสมอ

  • chain ที่​ไม่​ประกาศ securityMatcher ต้อง​เป็น​ตัว​สุดท้าย
  • chain ที่​ประกาศ​ไว้ ต้อง​เรียง​จาก​ขอบเขต​แคบ​ไป​กว้าง
  • อย่า​เชื่อ​รหัส​ตอบ​กลับ​เพื่อ​พิสูจน์​ว่า chain ไหน​ทำงาน ให้​ใส่​ป้าย​แล้ว​วัด​ป้าย

จัด​โครง​เป็น​แล้ว แต่ body ของ​คำ​ตอบ​ที่​ปฏิเสธ​ยัง​ว่าง​เปล่า​เหมือน​บท​ที่ 1

ตั้งแต่​บท​แรก​จนถึง​บท​นี้ ผู้​เรียก​ที่​ถูก​ปฏิเสธ​ยัง​ได้​แต่​ตัวเลข · บท​ถัด​ไป​เอา body กลับ​เข้า​สัญญา​เดิม และ​วัด​ว่า​ต้อง​ลงมือ​กี่​ที่

ที่มา​ของ​ตัวเลข​ใน​บท​นี้
  • Spring Boot 4.1.1 · Spring Security 7.1.1 · Kotlin 2.4.10 · JDK 25
  • รัน​ซ้ำ​เอง​ได้​ด้วย npm run verify:clinic-security · ต้อง​สั่ง scripts/clinic-security/up.sh ก่อน เพราะ​ทรง​ของ​บท​ที่ 7 ต้อง​ใช้​ฐาน​ข้อมูล
  • ชื่อ exception กับ​ป้าย​ของ chain ถูก​ตรึง​ไว้​ที่ src/data/perf/clinic-security.ts และ test/course-clinic-security.test.ts ผูก​สิ่ง​ที่​บท​นี้​พิมพ์​เข้า​กับ file นั้น
  • Spring Security — Java Configuration (เข้า​ถึง 2026-09-02) — การ​ประกาศ​หลาย SecurityFilterChain และ securityMatcher

เช็กความเข้าใจ — บทที่ 4

ข้อ 1 / 3

ประกาศ chain ที่ไม่มี `securityMatcher` ไว้เป็นตัวแรก แล้วเกิดอะไรขึ้น