Spring Webflux va CORS

All lectures for UZ purposes
Daraja, Dars
Mavjud

Spring MVC CORS (turli manbalar o'rtasida resurslar almashinuvi)ni boshqarishga imkon beradi.

Xavfsizlik nuqtai nazaridan brauzerlar joriy kelib chiqishdan tashqaridagi resurslarga AJAX murojaatlarini taqiqlaydi. Masalan, sizda bir varaqda bank hisobingiz bo'lishi mumkin, boshqa varaqda esa evil.com. Evil.com saytining scriptlari sizning bank APIingizga AJAX so'rovlarini yuborish imkoniyatiga ega bo'lmasligi kerak - masalan, hisobingizdan pul olish!

Turli manbalar o'rtasida resurslar almashinuvi (CORS) - bu W3C spetsifikatsiyasi, ko'pgina brauzerlarda bajarilgan, va u qaysi domenlararo so'rovlarning ruxsat etilganligini aniqlash imkonini beradi, shunda IFRAME yoki JSONP kabi kamroq xavfsiz va kamroq kuchli aylanish yo'llarini ishlatish o'rniga.

Qayta ishlash

CORS spetsifikatsiyasi preflight, oddiy va haqiqiy so'rovlar orasidagi farqni qiladi. CORS qanday ishlashini tushunmoqchi bo'lsangiz, ushbu maqolani ko'rib chiqishingiz mumkin yoki boshqa xususiyatlar bo'yicha ma'lumot olishingiz mumkin.

Spring WebFlux'dan HandlerMapping realizatsiyalari CORS uchun o'rnatilgan qo'llab-quvvatlashni ta'minlaydi. So'rov muvaffaqiyatli ravishda qayta ishlovchiga moslashtirilganidan so'ng, HandlerMapping ushbu so'rov va ishlovchi uchun CORS konfiguratsiyasini tekshiradi va keyingi harakatlarni amalga oshiradi. Preflight so'rovlari bevosita qayta ishlanadi, oddiy va haqiqiy CORS so'rovlari esa ushlanadi, tekshiriladi va kerakli CORS javob sarlavhalari o‘rnatiladi.

Turli manbalar o'rtasida so'rovlarni ruxsat berish uchun (ya'ni Origin sarlavhasi mavjud bo'lib, so'rov mezbonidan farq qilsa), sizga CORSning aniq e'lon qilingan konfiguratsiyasini ta'minlashingiz kerak. Mos konfiguratsiyasi topilmasa, preflight so'rovlari rad etiladi. Oddiy va haqiqiy CORS soʻrovlarga CORS sarlavhalari qoʻshilmaydi va shuning uchun brauzerlar ularni rad etadi.

Har bir HandlerMapping URL-shablonlar asosida CorsConfiguration xaritalashlaridan foydalanib, alohida sozlanishi mumkin. Ko'p hollarda ilovalar bunday xaritalashlar e'lon qilish uchun WebFlux Java konfiguratsiyasidan foydalanadi, bu esa barcha HandlerMapping realizatsiyalariga uzatiladigan yagona umumiy Map yaratishga olib keladi.

HandlerMapping darajasida umumiy CORS konfiguratsiyasini yanada nozikroq ishlovchi darajasida CORS sozlashi bilan birlashtirish mumkin. Masalan, anotatsiyalangan kontrollerlar @CrossOrigin anotatsiyasidan sinf yoki metod darajasida foydalanishi mumkin (boshqa ishlovchilar CorsConfigurationSource ni amalga oshirishi mumkin).

Umumiy va mahalliy konfiguratsiyalarni birlashtirish qoidalari odatda qo'shimcha ravishda - masalan, barcha umumiy va barcha mahalliy manbalar. Birgina qiymat qabul qilinishi mumkin bo'lgan atributlar uchun, masalan, allowCredentials va maxAge, mahalliy qiymat umumiy qiymatni o'rnini bosadi. Batafsilroq ma'lumot olish uchun CorsConfiguration#combine(CorsConfiguration) bo'limiga qarang.

Asl manbadan ko'proq ma'lumot olish yoki kengaytirilgan sozlash uchun, qarang:

  • CorsConfiguration

  • CorsProcessor va DefaultCorsProcessor

  • AbstractHandlerMapping

@CrossOrigin

@CrossOrigin annotatsiyasi tasvirlangan kontroller metodlariga turli manbalar o'rtasida so'rovlar amalga oshirish imkoniyatini beradi, quyidagi misolda ko'rsatilganidek:

Java
@RestController
@RequestMapping("/account")
public class AccountController {
@CrossOrigin
@GetMapping("/{id}")
public Mono<Account> retrieve(@PathVariable Long id) {
// ...
}
@DeleteMapping("/{id}")
public Mono<Void> remove(@PathVariable Long id) {
// ...
}
}
Kotlin
@RestController
@RequestMapping("/account")
class AccountController {
@CrossOrigin
@GetMapping("/{id}")
suspend fun retrieve(@PathVariable id: Long): Account {
// ...
}
@DeleteMapping("/{id}")
suspend fun remove(@PathVariable id: Long) {
// ...
}
}

Standart holatda @CrossOrigin ga ruxsat etiladi:

  • Hammasi manbalar.

  • Hammasi sarlavhalar.

  • Kontroller metodiga mos kelgan barcha HTTP metodlar.

allowCredentials standart holatda faollashtirilmagan, chunki bu foydalanuvchi haqida maxfiy ma'lumotlarni (masalan, cookie fayllar va CSRF tokenlar) ochilishini ta'minlaydigan ishonch darajasini o'rnatadi, shuning uchun uni faqat zarur hollarda ishlatish kerak. Agar u faollashtirilgan bo'lsa, ya'ni allowOrigins bir yoki bir nechta aniq domenlar uchun o‘rnatilgan bo‘lishi kerak (lekin "*" maxsus qiymat emas), yoki, alternativ ravishda, dinamik manbalar to‘plamini moslashtirish uchun allowOriginPatterns xususiyatidan foydalanish mumkin.

maxAge 30 daqiqa qilib o'rnatilgan.

@CrossOrigin sinf darajasida ham qo‘llab-quvvatlanadi va barcha metodlarga meros bo‘lib keladi. Quyidagi misolda aniq domen ko‘rsatilgan va maxAge qiymati bir soat qilib o‘rnatilgan:

Java
@CrossOrigin(origins = "https://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {
@GetMapping("/{id}")
public Mono<Account> retrieve(@PathVariable Long id) {
// ...
}
@DeleteMapping("/{id}")
public Mono<Void> remove(@PathVariable Long id) {
// ...
}
}
Kotlin
@CrossOrigin("https://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
class AccountController {
@GetMapping("/{id}")
suspend fun retrieve(@PathVariable id: Long): Account {
// ...
}
@DeleteMapping("/{id}")
suspend fun remove(@PathVariable id: Long) {
// ...
}
}

Sinf darajasida ham, metod darajasida ham @CrossOrigin annotatsiyasidan foydalanishingiz mumkin, quyidagi misolda tasvirlanganidek:

Java
@CrossOrigin(maxAge = 3600) 
@RestController
@RequestMapping("/account")
public class AccountController {
@CrossOrigin("https://domain2.com") 
@GetMapping("/{id}")
public Mono<Account> retrieve(@PathVariable Long id) {
// ...
}
@DeleteMapping("/{id}")
public Mono<Void> remove(@PathVariable Long id) {
// ...
}
}
  1. Sinf darajasida @CrossOrigin annotatsiyasidan foydalanish.
  2. Metod darajasida @CrossOrigin annotatsiyasidan foydalanish.
Kotlin
@CrossOrigin(maxAge = 3600) 
@RestController
@RequestMapping("/account")
class AccountController {
@CrossOrigin("https://domain2.com") 
@GetMapping("/{id}")
suspend fun retrieve(@PathVariable id: Long): Account {
// ...
}
@DeleteMapping("/{id}")
suspend fun remove(@PathVariable id: Long) {
// ...
}
}
  1. Sinf darajasida @CrossOrigin annotatsiyasidan foydalanish.
  2. Metod darajasida @CrossOrigin annotatsiyasidan foydalanish.

Umumiy konfiguratsiya

Kontroller metodlari darajasida nozik sozlashingizdan tashqari, ehtimol sizga umumiy CORS konfiguratsiyasini ham aniqlashingiz kerak bo'ladi. Har qanday HandlerMapping uchun URL-manzillar asosida CorsConfiguration xaritalashlarini alohida sozlashingiz mumkin. Ammo, ko'pchilik ilovalar uchun WebFlux Java konfiguratsiyasidan foydalanadi.

Standart holatda umumiy konfiguratsiya quyidagilarni o'z ichiga oladi:

  • Hammasi manbalar.

  • Hammasi sarlavhalar.

  • GET, HEAD va POST metodlari.

allowCredentials standart holatda faollashtirilmagan, chunki bu foydalanuvchi haqida maxfiy ma'lumotlarni (masalan, cookie fayllar va CSRF tokenlar) ochilishini ta'minlaydigan ishonch darajasini o'rnatadi, shuning uchun uni faqat zarur hollarda ishlatish kerak. Agar u faollashtirilgan bo'lsa, ya'ni allowOrigins bir yoki bir nechta aniq domenlar uchun o‘rnatilgan bo‘lishi kerak (lekin "*" maxsus qiymat emas), yoki, alternativ ravishda, dinamik manbalar to‘plamini moslashtirish uchun allowOriginPatterns xususiyatidan foydalanish mumkin.

maxAge 30 daqiqa qilib o'rnatilgan.

WebFlux Java konfiguratsiyasida CORSni faollashtirish uchun quyidagi misolda ko'rsatilganidek CorsRegistry qayta chaqiruvini ishlatishingiz mumkin:

Java
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
    .allowedOrigins("https://domain2.com")
    .allowedMethods("PUT", "DELETE")
    .allowedHeaders("header1", "header2", "header3")
    .exposedHeaders("header1", "header2")
    .allowCredentials(true).maxAge(3600);
// Qo'shimcha xaritalashlar qo'shish...
}
}
Kotlin
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {
override fun addCorsMappings(registry: CorsRegistry) {
registry.addMapping("/api/**")
        .allowedOrigins("https://domain2.com")
        .allowedMethods("PUT", "DELETE")
        .allowedHeaders("header1", "header2", "header3")
        .exposedHeaders("header1", "header2")
        .allowCredentials(true).maxAge(3600)
// Qo'shimcha xaritalashlar qo'shish...
}
}

CORS uchun WebFilter

Functional endpoints uchun ajoyib bo'lgan o'rnatilgan CorsWebFilter orqali CORSni qo'llab-quvvatlashni amalga oshirishingiz mumkin.

Agar Spring Security bilan CorsFilter dan foydalanishga harakat qilayotgan bo'lsangiz, Spring Security CORS uchun o'rnatilgan qo'llab-quvvatlanishni ta'minlaydi.

Filtrni sozlash uchun CorsWebFilter ni bean sifatida e'lon qilishingiz va uning konstruktoriga CorsConfigurationSource ni uzatishingiz mumkin, quyidagi misolda ko'rsatilganidek:

Java
@Bean
CorsWebFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
// Mumkin...
// config.applyPermitDefaultValues()
config.setAllowCredentials(true);
config.addAllowedOrigin("https://domain1.com");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}
Kotlin
@Bean
fun corsFilter(): CorsWebFilter {
val config = CorsConfiguration()
// Mumkin...
// config.applyPermitDefaultValues()
config.allowCredentials = true
config.addAllowedOrigin("https://domain1.com")
config.addAllowedHeader("*")
config.addAllowedMethod("*")
val source = UrlBasedCorsConfigurationSource().apply {
registerCorsConfiguration("/**", config)
}
return CorsWebFilter(source)
}
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION