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

config ที่​ยัง​ลอย​อยู่​ใน​บทความ แต่​คอม​ไพล์​ไม่​ผ่าน​แล้ว

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

⚙️ วิธี​วัด​ของ​บท​นี้

probe สร้าง​โปร​เจ​กต์ Gradle ขึ้น​ใหม่​ที​ละ​ทรง แล้ว​สั่ง :app:compileKotlin อย่าง​เดียว · ไม่​ได้​ส​ตาร์ต​แอป ไม่​ได้​ยิง​คำขอ · หน่วย​ของ​บท​นี้​มี​สอง​อย่าง

  • ผล​การ​คอม​ไพล์ ผ่าน​หรือ​ไม่​ผ่าน
  • ข้อความ​ที่ compiler พิมพ์​ออก​มา ยก​มา​ทั้ง​บรรทัด

ทรง​ควบคุม​ชื่อ baseline-sec7 ต้อง​คอม​ไพล์​ผ่าน​ก่อน​เสมอ · ถ้า​ทรง​นั้น​ไม่​ผ่าน probe จะ​บอก​ว่า วัด​ไม่​ได้ แทนที่​จะ​บอก​ว่า​ข้อ​อ้าง​ผิด เพราะ​การ​เทียบ​ทุก​ข้อ​จะ​ไม่มี​ความ​หมาย

รูป​นี้​ถูก​ต้อง​มา​หลาย​รุ่น และ​ยัง​อยู่​ใน​บทความ​จำนวน​มาก

❌ version ดิบ · แปะ​แล้ว​ไม่​คอม​ไพล์
@Bean
fun chain(http: HttpSecurity): SecurityFilterChain {
http.authorizeRequests { it.anyRequest().authenticated() }
return http.build()
}
e: Unresolved reference 'authorizeRequests'.
e: Unresolved reference 'it'.

ข้อความ​ที่​สอง​น่า​สนใจ​กว่า​ข้อความ​แรก · it ไม่มี​ตัว​ตน​เพราะ compiler ไม่รู้​ชนิด​ของ lambda เมื่อ method ที่​รับ lambda ไม่มี​อยู่ · ข้อ​ผิด​พลาด​หนึ่ง​จุด​จึง​พิมพ์​ออก​มาส​อง​บรรทัด

รูป​ที่​ใช้ได้​คือ authorizeHttpRequestsauthorizeHttpRequestsรูป​เดียว​ที่​เหลือ​อยู่​สำหรับ​ประกาศ​กฎ​ว่า​เส้น​ทาง​ไหน​ใคร​เรียก​ได้ · รุ่น 7 ถอด `authorizeRequests` ออก · วัด​แล้ว​ว่า code ที่​เรียก​ชื่อ​เก่า​ได้ `Unresolved reference` จาก compiler · ข้าง​หลัง​มัน​คือ AuthorizationFilterAuthorizationFilterfilter ที่​ตัดสิน​ว่า​คำขอ​ผ่าน​กฎ​หรือ​ไม่ · มา​แทน `FilterSecurityInterceptor` ของ​รุ่น​ก่อน · มัน​เป็น​ตัว​โยน exception ที่ `ExceptionTranslationFilter` รับ​ต่อ ซึ่ง​เป็น​ตัว​ตัดสิน​ว่า​คำขอ​ผ่าน​กฎ​หรือ​ไม่ และ​เป็น​ตัว​โยน exception ที่​บท​ก่อน​ตาม​รอย​ไว้

รูป​นี้​เคย​เป็น​วิธี​ร้อย​หลาย​เรื่อง​ไว้​ใน​ประโยค​เดียว

❌ version ดิบ · แปะ​แล้ว​ไม่​คอม​ไพล์
http.authorizeHttpRequests { it.anyRequest().authenticated() }
.and()
.httpBasic { }
e: Unresolved reference. None of the following candidates is applicable because of a receiver type mismatch:
e: Unresolved reference 'httpBasic'.

and() เคย​คืน​ค่า​เป็น​ตัว HttpSecurity เพื่อ​ให้​ต่อ​เรื่อง​ถัด​ไป​ได้ · เมื่อ​มัน​หาย​ไป httpBasic ที่​ห้อย​อยู่​ท้าย​สาย​จึง​หา​เจ้าของ​ไม่​เจอ

รูป​ที่​ใช้ได้​คือ​เรียก​ที​ละ​เรื่อง เรื่อง​ละ​บรรทัด แบบ​ที่ SecConfig ใน​บท​ก่อน​เขียน​ไว้

รูป​นี้​ไม่​ได้​เปลี่ยน​ชื่อ method มัน​เปลี่ยน​ที่​อยู่

❌ version ดิบ · import ของ​รุ่น​ก่อน
import org.springframework.security.config.annotation.ObjectPostProcessor
e: Unresolved reference 'ObjectPostProcessor'.

ObjectPostProcessorObjectPostProcessorช่อง​ที่​ให้​เรา​แตะ filter ที่ Spring สร้าง​ขึ้น​เอง ก่อน​มัน​ถูก​ใช้​งาน · **ย้าย package ใน​รุ่น 7** จาก `config.annotation` มา​เป็น `config` · path ของ​รุ่น 6 ให้ `Unresolved reference` ยัง​มี​อยู่ และ​ยัง​ทำงาน​เหมือน​เดิม · มัน​แค่​ย้าย package

รุ่นที่​อยู่
รุ่น​ก่อนorg.springframework.security.config.annotation.ObjectPostProcessor
รุ่น​ที่​เรา​ใช้org.springframework.security.config.ObjectPostProcessor
ข้อความ​เดียวกัน สอง​สาเหตุ​ที่​ต้อง​แยก​ให้​ออก

Unresolved reference ของ​รูป​ที่​หนึ่ง แปล​ว่าของ​นั้น​ไม่มี​แล้ว · Unresolved reference ของ​รูป​ที่​สาม แปล​ว่าของ​นั้น​มี​อยู่ แต่​คุณ​ชี้​ผิด​ที่

สอง​อย่าง​นี้​ให้​ข้อความ​เดีย​วกันเป๊ะ · การ​อ่าน​แล้ว​สรุป​ว่า “API นี้​ถูก​ถอด​ออก​แล้ว” จึง​ผิด​ได้​ครึ่ง​หนึ่ง​ของ​เวลา · ทาง​แยก​คือ​เปิด​หา​ชื่อ class ใน​ตัว jar ไม่ใช่​เดา​จาก​ข้อความ

รอบ​ที่​วัด​จริง​ของ​คอร์ส​นี้​พลาด​ข้อ​นี้​มา​แล้ว​หนึ่ง​ครั้ง · ร่าง​แรก​ของ probe เขียน import ผิด แล้ว​เกือบ​บันทึก​ว่า “ทาง​นี้​ใช้​ไม่​ได้” ทั้ง​ที่​ใช้ได้

สาม​บรรทัด ไม่มี​การ​ต่อ​ประโยค

✅ รูป​ที่​คอม​ไพล์​ผ่าน​บน​รุ่น​ที่​เรา​ใช้
@Configuration
class SecConfig {
@Bean
fun chain(http: HttpSecurity): SecurityFilterChain {
http.authorizeHttpRequests { it.anyRequest().authenticated() }
return http.build()
}
}

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

การ​คอม​ไพล์​ผ่าน ยัง​ไม่ใช่​หลัก​ฐาน​ว่า​มัน​ทำงาน

หัวข้อ​ที่​มีชื่อ​ว่า “การ​คอม​ไพล์​ผ่าน ยัง​ไม่ใช่​หลัก​ฐาน​ว่า​มัน​ทำงาน”

นี่​คือ​ประโยค​ที่​ทั้ง​คอร์ส​แขวน​อยู่ และ​บท​ที่ 3 จะ​พิสูจน์​มัน

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

ใน​หก​ทรง​ที่​ผ่าน มี​ทรง​หนึ่ง​ที่​บท​ถัด​ไป​วัด​ตอน​รัน​แล้ว​พบ​ว่าไม่มี​ผล​สัก​ช่อง · compiler ไม่มี​ทาง​เตือน​เรื่อง​นั้น เพราะ​มัน​ไม่ใช่​เรื่อง​ของ​ชนิด​ข้อมูล

สอง​คำถาม​ที่​ต้อง​ถาม​แยก​กัน
  • ชื่อ​นี้​มี​อยู่​ไหม · compileKotlin ตอบ​ได้
  • ของ​ชิ้น​นี้​ถูก​เรียก​ใช้​จริง​ไหม · ต้อง​ส​ตาร์ต​แอป​แล้ว​วัด

config ที่​ตอบ​ข้อ​แรก​ผ่าน​แต่​ตก​ข้อ​สอง คือ config ที่​อ่าน​แล้ว​ดูถูก​ทุก​บรรทัด และ​ไม่​ทำ​อะไร​เลย

เขียน config เป็น​แล้ว ยัง​ไม่รู้​ว่า​ใคร​เป็น​คน​เลือก​รหัส​ตอบ​กลับ

บท​ก่อน​วัด​ได้​ว่า​คำขอ​ที่​ไม่​ส่ง​รหัส​ผ่าน​ได้ 401 และ​คำขอ​ที่​สิทธิ์​ไม่​พอได้ 403 · กฎ​ที่​เรา​เขียน​ไม่มี​บรรทัด​ไหน​พูด​ถึง​ตัวเลข​สอง​ตัว​นั้น​เลย · บท​ถัด​ไป​หา​ว่า​ใคร​เป็น​คน​เลือก

ที่มา​ของ​ตัวเลข​ใน​บท​นี้
  • Spring Boot 4.1.1 · Spring Security 7.1.1 · Kotlin 2.4.10 · JDK 25
  • รัน​ซ้ำ​เอง​ได้​ด้วย npm run verify:clinic-security-shapes ซึ่ง​คอม​ไพล์​เก้า​ทรง แล้ว​เทียบ​ผล​ที​ละ​ทรง · ไม่​ต้อง​ใช้ Docker และ​ไม่​ต้อง​ใช้​ฐาน​ข้อมูล
  • ข้อความ compiler ทุก​บรรทัด​ใน​บท​นี้​ถูก​ตรึง​ไว้​ที่ src/data/perf/clinic-security-shapes.ts และ test/course-clinic-security.test.ts ผูก​ข้อความ​ใน​บท​เข้า​กับ file นั้น
  • Spring Security — What’s New in 7.0 (เข้า​ถึง 2026-09-02) — รายการ​สิ่ง​ที่​ถูก​ถอด​ออก​จาก DSL

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

ข้อ 1 / 3

ทำไมรูปที่ใช้ `authorizeRequests` ถึงพิมพ์ข้อผิดพลาดออกมาสองบรรทัด ทั้งที่เขียนผิดจุดเดียว